OSDN Git Service

Merge "Add FLAG_ACTIVITY_NEW_TASK when starting UI-based tether provisioning."
[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.FIRST_DYNAMIC_STACK_ID;
32 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
33 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
34 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
35 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
36 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
37 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
38 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
39 import static android.content.pm.PackageManager.GET_PROVIDERS;
40 import static android.content.pm.PackageManager.MATCH_ANY_USER;
41 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
42 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
43 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
44 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
45 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
46 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
47 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
48 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
49 import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
50 import static android.os.Build.VERSION_CODES.N;
51 import static android.os.Process.BLUETOOTH_UID;
52 import static android.os.Process.FIRST_APPLICATION_UID;
53 import static android.os.Process.FIRST_ISOLATED_UID;
54 import static android.os.Process.LAST_ISOLATED_UID;
55 import static android.os.Process.NFC_UID;
56 import static android.os.Process.PHONE_UID;
57 import static android.os.Process.PROC_CHAR;
58 import static android.os.Process.PROC_OUT_LONG;
59 import static android.os.Process.PROC_PARENS;
60 import static android.os.Process.PROC_SPACE_TERM;
61 import static android.os.Process.ProcessStartResult;
62 import static android.os.Process.ROOT_UID;
63 import static android.os.Process.SCHED_FIFO;
64 import static android.os.Process.SCHED_OTHER;
65 import static android.os.Process.SCHED_RESET_ON_FORK;
66 import static android.os.Process.SHELL_UID;
67 import static android.os.Process.SIGNAL_QUIT;
68 import static android.os.Process.SIGNAL_USR1;
69 import static android.os.Process.SYSTEM_UID;
70 import static android.os.Process.THREAD_GROUP_BG_NONINTERACTIVE;
71 import static android.os.Process.THREAD_GROUP_DEFAULT;
72 import static android.os.Process.THREAD_GROUP_TOP_APP;
73 import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
74 import static android.os.Process.THREAD_PRIORITY_FOREGROUND;
75 import static android.os.Process.getFreeMemory;
76 import static android.os.Process.getTotalMemory;
77 import static android.os.Process.isThreadInProcess;
78 import static android.os.Process.killProcess;
79 import static android.os.Process.killProcessQuiet;
80 import static android.os.Process.myPid;
81 import static android.os.Process.myUid;
82 import static android.os.Process.readProcFile;
83 import static android.os.Process.removeAllProcessGroups;
84 import static android.os.Process.sendSignal;
85 import static android.os.Process.setProcessGroup;
86 import static android.os.Process.setThreadPriority;
87 import static android.os.Process.setThreadScheduler;
88 import static android.os.Process.startWebView;
89 import static android.os.Process.zygoteProcess;
90 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
91 import static android.provider.Settings.Global.DEBUG_APP;
92 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
93 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
94 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
95 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
96 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
97 import static android.provider.Settings.System.FONT_SCALE;
98 import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
99 import static android.text.format.DateUtils.DAY_IN_MILLIS;
100 import static android.view.Display.DEFAULT_DISPLAY;
101 import static android.view.Display.INVALID_DISPLAY;
102 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
103 import static com.android.internal.util.XmlUtils.readIntAttribute;
104 import static com.android.internal.util.XmlUtils.readLongAttribute;
105 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
106 import static com.android.internal.util.XmlUtils.writeIntAttribute;
107 import static com.android.internal.util.XmlUtils.writeLongAttribute;
108 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
109 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
110 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
111 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
112 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
113 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
114 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
115 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
116 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
117 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
118 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
119 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
120 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
121 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
122 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_NETWORK;
123 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
124 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON;
125 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
126 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
127 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
128 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
129 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
130 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
131 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
132 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
133 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
134 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
135 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
136 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
137 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
138 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
139 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
140 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
141 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
142 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
143 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
144 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
145 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
146 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
147 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
148 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
149 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
150 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
151 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_NETWORK;
152 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
153 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
154 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
155 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
156 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
157 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
158 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
159 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
160 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
161 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
162 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
163 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
164 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
165 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
166 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
167 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
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.ScreenObserver;
204 import android.app.ActivityManagerInternal.SleepToken;
205 import android.app.ActivityOptions;
206 import android.app.ActivityThread;
207 import android.app.AlertDialog;
208 import android.app.AppGlobals;
209 import android.app.AppOpsManager;
210 import android.app.ApplicationErrorReport;
211 import android.app.ApplicationThreadConstants;
212 import android.app.BroadcastOptions;
213 import android.app.ContentProviderHolder;
214 import android.app.Dialog;
215 import android.app.IActivityController;
216 import android.app.IActivityManager;
217 import android.app.IAppTask;
218 import android.app.IApplicationThread;
219 import android.app.IInstrumentationWatcher;
220 import android.app.INotificationManager;
221 import android.app.IProcessObserver;
222 import android.app.IServiceConnection;
223 import android.app.IStopUserCallback;
224 import android.app.ITaskStackListener;
225 import android.app.IUiAutomationConnection;
226 import android.app.IUidObserver;
227 import android.app.IUserSwitchObserver;
228 import android.app.Instrumentation;
229 import android.app.Notification;
230 import android.app.NotificationManager;
231 import android.app.PendingIntent;
232 import android.app.PictureInPictureParams;
233 import android.app.ProfilerInfo;
234 import android.app.RemoteAction;
235 import android.app.WaitResult;
236 import android.app.admin.DevicePolicyManager;
237 import android.app.assist.AssistContent;
238 import android.app.assist.AssistStructure;
239 import android.app.backup.IBackupManager;
240 import android.app.usage.UsageEvents;
241 import android.app.usage.UsageStatsManagerInternal;
242 import android.appwidget.AppWidgetManager;
243 import android.content.ActivityNotFoundException;
244 import android.content.BroadcastReceiver;
245 import android.content.ClipData;
246 import android.content.ComponentCallbacks2;
247 import android.content.ComponentName;
248 import android.content.ContentProvider;
249 import android.content.ContentResolver;
250 import android.content.Context;
251 import android.content.DialogInterface;
252 import android.content.IContentProvider;
253 import android.content.IIntentReceiver;
254 import android.content.IIntentSender;
255 import android.content.Intent;
256 import android.content.IntentFilter;
257 import android.content.pm.ActivityInfo;
258 import android.content.pm.ApplicationInfo;
259 import android.content.pm.ConfigurationInfo;
260 import android.content.pm.IPackageDataObserver;
261 import android.content.pm.IPackageManager;
262 import android.content.pm.InstrumentationInfo;
263 import android.content.pm.PackageInfo;
264 import android.content.pm.PackageManager;
265 import android.content.pm.PackageManager.NameNotFoundException;
266 import android.content.pm.PackageManagerInternal;
267 import android.content.pm.ParceledListSlice;
268 import android.content.pm.PathPermission;
269 import android.content.pm.PermissionInfo;
270 import android.content.pm.ProviderInfo;
271 import android.content.pm.ResolveInfo;
272 import android.content.pm.SELinuxUtil;
273 import android.content.pm.ServiceInfo;
274 import android.content.pm.UserInfo;
275 import android.content.res.CompatibilityInfo;
276 import android.content.res.Configuration;
277 import android.content.res.Resources;
278 import android.database.ContentObserver;
279 import android.graphics.Bitmap;
280 import android.graphics.Point;
281 import android.graphics.Rect;
282 import android.location.LocationManager;
283 import android.media.audiofx.AudioEffect;
284 import android.metrics.LogMaker;
285 import android.net.Proxy;
286 import android.net.ProxyInfo;
287 import android.net.Uri;
288 import android.os.BatteryStats;
289 import android.os.Binder;
290 import android.os.Build;
291 import android.os.Bundle;
292 import android.os.Debug;
293 import android.os.DropBoxManager;
294 import android.os.Environment;
295 import android.os.FactoryTest;
296 import android.os.FileObserver;
297 import android.os.FileUtils;
298 import android.os.Handler;
299 import android.os.IBinder;
300 import android.os.IDeviceIdentifiersPolicyService;
301 import android.os.IPermissionController;
302 import android.os.IProcessInfoService;
303 import android.os.IProgressListener;
304 import android.os.LocaleList;
305 import android.os.Looper;
306 import android.os.Message;
307 import android.os.Parcel;
308 import android.os.ParcelFileDescriptor;
309 import android.os.PersistableBundle;
310 import android.os.PowerManager;
311 import android.os.PowerManagerInternal;
312 import android.os.Process;
313 import android.os.RemoteCallbackList;
314 import android.os.RemoteException;
315 import android.os.ResultReceiver;
316 import android.os.ServiceManager;
317 import android.os.ShellCallback;
318 import android.os.StrictMode;
319 import android.os.SystemClock;
320 import android.os.SystemProperties;
321 import android.os.Trace;
322 import android.os.TransactionTooLargeException;
323 import android.os.UpdateLock;
324 import android.os.UserHandle;
325 import android.os.UserManager;
326 import android.os.WorkSource;
327 import android.os.storage.IStorageManager;
328 import android.os.storage.StorageManager;
329 import android.os.storage.StorageManagerInternal;
330 import android.provider.Downloads;
331 import android.provider.Settings;
332 import android.service.voice.IVoiceInteractionSession;
333 import android.service.voice.VoiceInteractionManagerInternal;
334 import android.service.voice.VoiceInteractionSession;
335 import android.telecom.TelecomManager;
336 import android.text.TextUtils;
337 import android.text.format.DateUtils;
338 import android.text.format.Time;
339 import android.text.style.SuggestionSpan;
340 import android.util.ArrayMap;
341 import android.util.ArraySet;
342 import android.util.AtomicFile;
343 import android.util.TimingsTraceLog;
344 import android.util.DebugUtils;
345 import android.util.DisplayMetrics;
346 import android.util.EventLog;
347 import android.util.Log;
348 import android.util.Pair;
349 import android.util.PrintWriterPrinter;
350 import android.util.Slog;
351 import android.util.SparseArray;
352 import android.util.SparseIntArray;
353 import android.util.TimeUtils;
354 import android.util.Xml;
355 import android.view.Gravity;
356 import android.view.LayoutInflater;
357 import android.view.View;
358 import android.view.WindowManager;
359
360 import com.android.server.job.JobSchedulerInternal;
361 import com.google.android.collect.Lists;
362 import com.google.android.collect.Maps;
363
364 import com.android.internal.R;
365 import com.android.internal.annotations.GuardedBy;
366 import com.android.internal.annotations.VisibleForTesting;
367 import com.android.internal.app.AssistUtils;
368 import com.android.internal.app.DumpHeapActivity;
369 import com.android.internal.app.IAppOpsCallback;
370 import com.android.internal.app.IAppOpsService;
371 import com.android.internal.app.IVoiceInteractor;
372 import com.android.internal.app.ProcessMap;
373 import com.android.internal.app.SystemUserHomeActivity;
374 import com.android.internal.app.procstats.ProcessStats;
375 import com.android.internal.logging.MetricsLogger;
376 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
377 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
378 import com.android.internal.notification.SystemNotificationChannels;
379 import com.android.internal.os.BackgroundThread;
380 import com.android.internal.os.BatteryStatsImpl;
381 import com.android.internal.os.IResultReceiver;
382 import com.android.internal.os.ProcessCpuTracker;
383 import com.android.internal.os.TransferPipe;
384 import com.android.internal.os.Zygote;
385 import com.android.internal.policy.IKeyguardDismissCallback;
386 import com.android.internal.telephony.TelephonyIntents;
387 import com.android.internal.util.ArrayUtils;
388 import com.android.internal.util.DumpUtils;
389 import com.android.internal.util.FastPrintWriter;
390 import com.android.internal.util.FastXmlSerializer;
391 import com.android.internal.util.MemInfoReader;
392 import com.android.internal.util.Preconditions;
393 import com.android.server.AppOpsService;
394 import com.android.server.AttributeCache;
395 import com.android.server.DeviceIdleController;
396 import com.android.server.IntentResolver;
397 import com.android.server.LocalServices;
398 import com.android.server.LockGuard;
399 import com.android.server.NetworkManagementInternal;
400 import com.android.server.RescueParty;
401 import com.android.server.ServiceThread;
402 import com.android.server.SystemConfig;
403 import com.android.server.SystemService;
404 import com.android.server.SystemServiceManager;
405 import com.android.server.ThreadPriorityBooster;
406 import com.android.server.Watchdog;
407 import com.android.server.am.ActivityStack.ActivityState;
408 import com.android.server.firewall.IntentFirewall;
409 import com.android.server.pm.Installer;
410 import com.android.server.pm.Installer.InstallerException;
411 import com.android.server.statusbar.StatusBarManagerInternal;
412 import com.android.server.vr.VrManagerInternal;
413 import com.android.server.wm.PinnedStackWindowController;
414 import com.android.server.wm.WindowManagerService;
415
416 import java.text.SimpleDateFormat;
417 import org.xmlpull.v1.XmlPullParser;
418 import org.xmlpull.v1.XmlPullParserException;
419 import org.xmlpull.v1.XmlSerializer;
420
421 import java.io.File;
422 import java.io.FileDescriptor;
423 import java.io.FileInputStream;
424 import java.io.FileNotFoundException;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import java.io.InputStreamReader;
428 import java.io.PrintWriter;
429 import java.io.StringWriter;
430 import java.io.UnsupportedEncodingException;
431 import java.lang.ref.WeakReference;
432 import java.nio.charset.StandardCharsets;
433 import java.text.DateFormat;
434 import java.util.ArrayList;
435 import java.util.Arrays;
436 import java.util.Collections;
437 import java.util.Comparator;
438 import java.util.Date;
439 import java.util.HashMap;
440 import java.util.HashSet;
441 import java.util.Iterator;
442 import java.util.List;
443 import java.util.Locale;
444 import java.util.Map;
445 import java.util.Objects;
446 import java.util.Set;
447 import java.util.concurrent.CountDownLatch;
448 import java.util.concurrent.atomic.AtomicBoolean;
449 import java.util.concurrent.atomic.AtomicLong;
450
451 import dalvik.system.VMRuntime;
452 import libcore.io.IoUtils;
453 import libcore.util.EmptyArray;
454
455 public class ActivityManagerService extends IActivityManager.Stub
456         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
457
458     /**
459      * Priority we boost main thread and RT of top app to.
460      */
461     public static final int TOP_APP_PRIORITY_BOOST = -10;
462
463     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
464     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
465     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
466     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
467     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
468     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
469     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
470     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
471     private static final String TAG_LRU = TAG + POSTFIX_LRU;
472     private static final String TAG_MU = TAG + POSTFIX_MU;
473     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
474     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
475     private static final String TAG_POWER = TAG + POSTFIX_POWER;
476     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
477     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
478     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
479     private static final String TAG_PSS = TAG + POSTFIX_PSS;
480     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
481     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
482     private static final String TAG_STACK = TAG + POSTFIX_STACK;
483     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
484     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
485     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
486     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
487
488     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
489     // here so that while the job scheduler can depend on AMS, the other way around
490     // need not be the case.
491     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
492
493     /** Control over CPU and battery monitoring */
494     // write battery stats every 30 minutes.
495     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
496     static final boolean MONITOR_CPU_USAGE = true;
497     // don't sample cpu less than every 5 seconds.
498     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
499     // wait possibly forever for next cpu sample.
500     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
501     static final boolean MONITOR_THREAD_CPU_USAGE = false;
502
503     // The flags that are set for all calls we make to the package manager.
504     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
505
506     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
507
508     // Amount of time after a call to stopAppSwitches() during which we will
509     // prevent further untrusted switches from happening.
510     static final long APP_SWITCH_DELAY_TIME = 5*1000;
511
512     // How long we wait for a launched process to attach to the activity manager
513     // before we decide it's never going to come up for real.
514     static final int PROC_START_TIMEOUT = 10*1000;
515     // How long we wait for an attached process to publish its content providers
516     // before we decide it must be hung.
517     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
518
519     // How long we wait for a launched process to attach to the activity manager
520     // before we decide it's never going to come up for real, when the process was
521     // started with a wrapper for instrumentation (such as Valgrind) because it
522     // could take much longer than usual.
523     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
524
525     // How long we allow a receiver to run before giving up on it.
526     static final int BROADCAST_FG_TIMEOUT = 10*1000;
527     static final int BROADCAST_BG_TIMEOUT = 60*1000;
528
529     // How long we wait until we timeout on key dispatching.
530     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
531
532     // How long we wait until we timeout on key dispatching during instrumentation.
533     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
534
535     // How long to wait in getAssistContextExtras for the activity and foreground services
536     // to respond with the result.
537     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
538
539     // How long top wait when going through the modern assist (which doesn't need to block
540     // on getting this result before starting to launch its UI).
541     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
542
543     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
544     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
545
546     // Maximum number of persisted Uri grants a package is allowed
547     static final int MAX_PERSISTED_URI_GRANTS = 128;
548
549     static final int MY_PID = myPid();
550
551     static final String[] EMPTY_STRING_ARRAY = new String[0];
552
553     // How many bytes to write into the dropbox log before truncating
554     static final int DROPBOX_MAX_SIZE = 192 * 1024;
555     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
556     // as one line, but close enough for now.
557     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
558
559     // Access modes for handleIncomingUser.
560     static final int ALLOW_NON_FULL = 0;
561     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
562     static final int ALLOW_FULL_ONLY = 2;
563
564     // Necessary ApplicationInfo flags to mark an app as persistent
565     private static final int PERSISTENT_MASK =
566             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
567
568     // Intent sent when remote bugreport collection has been completed
569     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
570             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
571
572     // Used to indicate that an app transition should be animated.
573     static final boolean ANIMATE = true;
574
575     // Determines whether to take full screen screenshots
576     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
577
578     /**
579      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
580      */
581     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
582
583     /**
584      * State indicating that there is no need for any blocking for network.
585      */
586     @VisibleForTesting
587     static final int NETWORK_STATE_NO_CHANGE = 0;
588
589     /**
590      * State indicating that the main thread needs to be informed about the network wait.
591      */
592     @VisibleForTesting
593     static final int NETWORK_STATE_BLOCK = 1;
594
595     /**
596      * State indicating that any threads waiting for network state to get updated can be unblocked.
597      */
598     @VisibleForTesting
599     static final int NETWORK_STATE_UNBLOCK = 2;
600
601     // Max character limit for a notification title. If the notification title is larger than this
602     // the notification will not be legible to the user.
603     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
604
605     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
606
607     /** All system services */
608     SystemServiceManager mSystemServiceManager;
609     AssistUtils mAssistUtils;
610
611     private Installer mInstaller;
612
613     /** Run all ActivityStacks through this */
614     final ActivityStackSupervisor mStackSupervisor;
615     private final KeyguardController mKeyguardController;
616
617     final ActivityStarter mActivityStarter;
618
619     final TaskChangeNotificationController mTaskChangeNotificationController;
620
621     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
622
623     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
624
625     public final IntentFirewall mIntentFirewall;
626
627     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
628     // default action automatically.  Important for devices without direct input
629     // devices.
630     private boolean mShowDialogs = true;
631
632     private final VrController mVrController;
633
634     // VR Vr2d Display Id.
635     int mVr2dDisplayId = INVALID_DISPLAY;
636
637     // Whether we should use SCHED_FIFO for UI and RenderThreads.
638     private boolean mUseFifoUiScheduling = false;
639
640     BroadcastQueue mFgBroadcastQueue;
641     BroadcastQueue mBgBroadcastQueue;
642     // Convenient for easy iteration over the queues. Foreground is first
643     // so that dispatch of foreground broadcasts gets precedence.
644     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
645
646     BroadcastStats mLastBroadcastStats;
647     BroadcastStats mCurBroadcastStats;
648
649     BroadcastQueue broadcastQueueForIntent(Intent intent) {
650         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
651         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
652                 "Broadcast intent " + intent + " on "
653                 + (isFg ? "foreground" : "background") + " queue");
654         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
655     }
656
657     /**
658      * The last resumed activity. This is identical to the current resumed activity most
659      * of the time but could be different when we're pausing one activity before we resume
660      * another activity.
661      */
662     private ActivityRecord mLastResumedActivity;
663
664     /**
665      * If non-null, we are tracking the time the user spends in the currently focused app.
666      */
667     private AppTimeTracker mCurAppTimeTracker;
668
669     /**
670      * List of intents that were used to start the most recent tasks.
671      */
672     final RecentTasks mRecentTasks;
673
674     /**
675      * For addAppTask: cached of the last activity component that was added.
676      */
677     ComponentName mLastAddedTaskComponent;
678
679     /**
680      * For addAppTask: cached of the last activity uid that was added.
681      */
682     int mLastAddedTaskUid;
683
684     /**
685      * For addAppTask: cached of the last ActivityInfo that was added.
686      */
687     ActivityInfo mLastAddedTaskActivity;
688
689     /**
690      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
691      */
692     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
693
694     /**
695      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
696      */
697     String mDeviceOwnerName;
698
699     final UserController mUserController;
700
701     final AppErrors mAppErrors;
702
703     /**
704      * Dump of the activity state at the time of the last ANR. Cleared after
705      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
706      */
707     String mLastANRState;
708
709     /**
710      * Indicates the maximum time spent waiting for the network rules to get updated.
711      */
712     @VisibleForTesting
713     long mWaitForNetworkTimeoutMs;
714
715     public boolean canShowErrorDialogs() {
716         return mShowDialogs && !mSleeping && !mShuttingDown
717                 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
718                 && !(UserManager.isDeviceInDemoMode(mContext)
719                         && mUserController.getCurrentUser().isDemo());
720     }
721
722     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
723             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
724
725     static void boostPriorityForLockedSection() {
726         sThreadPriorityBooster.boost();
727     }
728
729     static void resetPriorityAfterLockedSection() {
730         sThreadPriorityBooster.reset();
731     }
732
733     public class PendingAssistExtras extends Binder implements Runnable {
734         public final ActivityRecord activity;
735         public boolean isHome;
736         public final Bundle extras;
737         public final Intent intent;
738         public final String hint;
739         public final IResultReceiver receiver;
740         public final int userHandle;
741         public boolean haveResult = false;
742         public Bundle result = null;
743         public AssistStructure structure = null;
744         public AssistContent content = null;
745         public Bundle receiverExtras;
746
747         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
748                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
749             activity = _activity;
750             extras = _extras;
751             intent = _intent;
752             hint = _hint;
753             receiver = _receiver;
754             receiverExtras = _receiverExtras;
755             userHandle = _userHandle;
756         }
757
758         @Override
759         public void run() {
760             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
761             synchronized (this) {
762                 haveResult = true;
763                 notifyAll();
764             }
765             pendingAssistExtrasTimedOut(this);
766         }
767     }
768
769     final ArrayList<PendingAssistExtras> mPendingAssistExtras
770             = new ArrayList<PendingAssistExtras>();
771
772     /**
773      * Process management.
774      */
775     final ProcessList mProcessList = new ProcessList();
776
777     /**
778      * All of the applications we currently have running organized by name.
779      * The keys are strings of the application package name (as
780      * returned by the package manager), and the keys are ApplicationRecord
781      * objects.
782      */
783     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
784
785     /**
786      * Tracking long-term execution of processes to look for abuse and other
787      * bad app behavior.
788      */
789     final ProcessStatsService mProcessStats;
790
791     /**
792      * The currently running isolated processes.
793      */
794     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
795
796     /**
797      * Counter for assigning isolated process uids, to avoid frequently reusing the
798      * same ones.
799      */
800     int mNextIsolatedProcessUid = 0;
801
802     /**
803      * The currently running heavy-weight process, if any.
804      */
805     ProcessRecord mHeavyWeightProcess = null;
806
807     /**
808      * Non-persistent appId whitelist for background restrictions
809      */
810     int[] mBackgroundAppIdWhitelist = new int[] {
811             BLUETOOTH_UID
812     };
813
814     /**
815      * Broadcast actions that will always be deliverable to unlaunched/background apps
816      */
817     ArraySet<String> mBackgroundLaunchBroadcasts;
818
819     /**
820      * All of the processes we currently have running organized by pid.
821      * The keys are the pid running the application.
822      *
823      * <p>NOTE: This object is protected by its own lock, NOT the global
824      * activity manager lock!
825      */
826     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
827
828     /**
829      * All of the processes that have been forced to be important.  The key
830      * is the pid of the caller who requested it (we hold a death
831      * link on it).
832      */
833     abstract class ImportanceToken implements IBinder.DeathRecipient {
834         final int pid;
835         final IBinder token;
836         final String reason;
837
838         ImportanceToken(int _pid, IBinder _token, String _reason) {
839             pid = _pid;
840             token = _token;
841             reason = _reason;
842         }
843
844         @Override
845         public String toString() {
846             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
847                     + " " + reason + " " + pid + " " + token + " }";
848         }
849     }
850     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
851
852     /**
853      * List of records for processes that someone had tried to start before the
854      * system was ready.  We don't start them at that point, but ensure they
855      * are started by the time booting is complete.
856      */
857     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
858
859     /**
860      * List of persistent applications that are in the process
861      * of being started.
862      */
863     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
864
865     /**
866      * Processes that are being forcibly torn down.
867      */
868     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
869
870     /**
871      * List of running applications, sorted by recent usage.
872      * The first entry in the list is the least recently used.
873      */
874     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
875
876     /**
877      * Where in mLruProcesses that the processes hosting activities start.
878      */
879     int mLruProcessActivityStart = 0;
880
881     /**
882      * Where in mLruProcesses that the processes hosting services start.
883      * This is after (lower index) than mLruProcessesActivityStart.
884      */
885     int mLruProcessServiceStart = 0;
886
887     /**
888      * List of processes that should gc as soon as things are idle.
889      */
890     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
891
892     /**
893      * Processes we want to collect PSS data from.
894      */
895     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
896
897     private boolean mBinderTransactionTrackingEnabled = false;
898
899     /**
900      * Last time we requested PSS data of all processes.
901      */
902     long mLastFullPssTime = SystemClock.uptimeMillis();
903
904     /**
905      * If set, the next time we collect PSS data we should do a full collection
906      * with data from native processes and the kernel.
907      */
908     boolean mFullPssPending = false;
909
910     /**
911      * This is the process holding what we currently consider to be
912      * the "home" activity.
913      */
914     ProcessRecord mHomeProcess;
915
916     /**
917      * This is the process holding the activity the user last visited that
918      * is in a different process from the one they are currently in.
919      */
920     ProcessRecord mPreviousProcess;
921
922     /**
923      * The time at which the previous process was last visible.
924      */
925     long mPreviousProcessVisibleTime;
926
927     /**
928      * Track all uids that have actively running processes.
929      */
930     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
931
932     /**
933      * This is for verifying the UID report flow.
934      */
935     static final boolean VALIDATE_UID_STATES = true;
936     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
937
938     /**
939      * Packages that the user has asked to have run in screen size
940      * compatibility mode instead of filling the screen.
941      */
942     final CompatModePackages mCompatModePackages;
943
944     /**
945      * Set of IntentSenderRecord objects that are currently active.
946      */
947     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
948             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
949
950     /**
951      * Fingerprints (hashCode()) of stack traces that we've
952      * already logged DropBox entries for.  Guarded by itself.  If
953      * something (rogue user app) forces this over
954      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
955      */
956     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
957     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
958
959     /**
960      * Strict Mode background batched logging state.
961      *
962      * The string buffer is guarded by itself, and its lock is also
963      * used to determine if another batched write is already
964      * in-flight.
965      */
966     private final StringBuilder mStrictModeBuffer = new StringBuilder();
967
968     /**
969      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
970      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
971      */
972     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
973
974     /**
975      * Resolver for broadcast intents to registered receivers.
976      * Holds BroadcastFilter (subclass of IntentFilter).
977      */
978     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
979             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
980         @Override
981         protected boolean allowFilterResult(
982                 BroadcastFilter filter, List<BroadcastFilter> dest) {
983             IBinder target = filter.receiverList.receiver.asBinder();
984             for (int i = dest.size() - 1; i >= 0; i--) {
985                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
986                     return false;
987                 }
988             }
989             return true;
990         }
991
992         @Override
993         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
994             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
995                     || userId == filter.owningUserId) {
996                 return super.newResult(filter, match, userId);
997             }
998             return null;
999         }
1000
1001         @Override
1002         protected BroadcastFilter[] newArray(int size) {
1003             return new BroadcastFilter[size];
1004         }
1005
1006         @Override
1007         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1008             return packageName.equals(filter.packageName);
1009         }
1010     };
1011
1012     /**
1013      * State of all active sticky broadcasts per user.  Keys are the action of the
1014      * sticky Intent, values are an ArrayList of all broadcasted intents with
1015      * that action (which should usually be one).  The SparseArray is keyed
1016      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1017      * for stickies that are sent to all users.
1018      */
1019     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1020             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1021
1022     final ActiveServices mServices;
1023
1024     final static class Association {
1025         final int mSourceUid;
1026         final String mSourceProcess;
1027         final int mTargetUid;
1028         final ComponentName mTargetComponent;
1029         final String mTargetProcess;
1030
1031         int mCount;
1032         long mTime;
1033
1034         int mNesting;
1035         long mStartTime;
1036
1037         // states of the source process when the bind occurred.
1038         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1039         long mLastStateUptime;
1040         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1041                 - ActivityManager.MIN_PROCESS_STATE+1];
1042
1043         Association(int sourceUid, String sourceProcess, int targetUid,
1044                 ComponentName targetComponent, String targetProcess) {
1045             mSourceUid = sourceUid;
1046             mSourceProcess = sourceProcess;
1047             mTargetUid = targetUid;
1048             mTargetComponent = targetComponent;
1049             mTargetProcess = targetProcess;
1050         }
1051     }
1052
1053     /**
1054      * When service association tracking is enabled, this is all of the associations we
1055      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1056      * -> association data.
1057      */
1058     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1059             mAssociations = new SparseArray<>();
1060     boolean mTrackingAssociations;
1061
1062     /**
1063      * Backup/restore process management
1064      */
1065     String mBackupAppName = null;
1066     BackupRecord mBackupTarget = null;
1067
1068     final ProviderMap mProviderMap;
1069
1070     /**
1071      * List of content providers who have clients waiting for them.  The
1072      * application is currently being launched and the provider will be
1073      * removed from this list once it is published.
1074      */
1075     final ArrayList<ContentProviderRecord> mLaunchingProviders
1076             = new ArrayList<ContentProviderRecord>();
1077
1078     /**
1079      * File storing persisted {@link #mGrantedUriPermissions}.
1080      */
1081     private final AtomicFile mGrantFile;
1082
1083     /** XML constants used in {@link #mGrantFile} */
1084     private static final String TAG_URI_GRANTS = "uri-grants";
1085     private static final String TAG_URI_GRANT = "uri-grant";
1086     private static final String ATTR_USER_HANDLE = "userHandle";
1087     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1088     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1089     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1090     private static final String ATTR_TARGET_PKG = "targetPkg";
1091     private static final String ATTR_URI = "uri";
1092     private static final String ATTR_MODE_FLAGS = "modeFlags";
1093     private static final String ATTR_CREATED_TIME = "createdTime";
1094     private static final String ATTR_PREFIX = "prefix";
1095
1096     /**
1097      * Global set of specific {@link Uri} permissions that have been granted.
1098      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1099      * to {@link UriPermission#uri} to {@link UriPermission}.
1100      */
1101     @GuardedBy("this")
1102     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1103             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1104
1105     public static class GrantUri {
1106         public final int sourceUserId;
1107         public final Uri uri;
1108         public boolean prefix;
1109
1110         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1111             this.sourceUserId = sourceUserId;
1112             this.uri = uri;
1113             this.prefix = prefix;
1114         }
1115
1116         @Override
1117         public int hashCode() {
1118             int hashCode = 1;
1119             hashCode = 31 * hashCode + sourceUserId;
1120             hashCode = 31 * hashCode + uri.hashCode();
1121             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1122             return hashCode;
1123         }
1124
1125         @Override
1126         public boolean equals(Object o) {
1127             if (o instanceof GrantUri) {
1128                 GrantUri other = (GrantUri) o;
1129                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1130                         && prefix == other.prefix;
1131             }
1132             return false;
1133         }
1134
1135         @Override
1136         public String toString() {
1137             String result = uri.toString() + " [user " + sourceUserId + "]";
1138             if (prefix) result += " [prefix]";
1139             return result;
1140         }
1141
1142         public String toSafeString() {
1143             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1144             if (prefix) result += " [prefix]";
1145             return result;
1146         }
1147
1148         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1149             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1150                     ContentProvider.getUriWithoutUserId(uri), false);
1151         }
1152     }
1153
1154     CoreSettingsObserver mCoreSettingsObserver;
1155
1156     FontScaleSettingObserver mFontScaleSettingObserver;
1157
1158     private final class FontScaleSettingObserver extends ContentObserver {
1159         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1160
1161         public FontScaleSettingObserver() {
1162             super(mHandler);
1163             ContentResolver resolver = mContext.getContentResolver();
1164             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1165         }
1166
1167         @Override
1168         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1169             if (mFontScaleUri.equals(uri)) {
1170                 updateFontScaleIfNeeded(userId);
1171             }
1172         }
1173     }
1174
1175     /**
1176      * Thread-local storage used to carry caller permissions over through
1177      * indirect content-provider access.
1178      */
1179     private class Identity {
1180         public final IBinder token;
1181         public final int pid;
1182         public final int uid;
1183
1184         Identity(IBinder _token, int _pid, int _uid) {
1185             token = _token;
1186             pid = _pid;
1187             uid = _uid;
1188         }
1189     }
1190
1191     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1192
1193     /**
1194      * All information we have collected about the runtime performance of
1195      * any user id that can impact battery performance.
1196      */
1197     final BatteryStatsService mBatteryStatsService;
1198
1199     /**
1200      * Information about component usage
1201      */
1202     UsageStatsManagerInternal mUsageStatsService;
1203
1204     /**
1205      * Access to DeviceIdleController service.
1206      */
1207     DeviceIdleController.LocalService mLocalDeviceIdleController;
1208
1209     /**
1210      * Set of app ids that are whitelisted for device idle and thus background check.
1211      */
1212     int[] mDeviceIdleWhitelist = new int[0];
1213
1214     /**
1215      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1216      */
1217     int[] mDeviceIdleTempWhitelist = new int[0];
1218
1219     static final class PendingTempWhitelist {
1220         final int targetUid;
1221         final long duration;
1222         final String tag;
1223
1224         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1225             targetUid = _targetUid;
1226             duration = _duration;
1227             tag = _tag;
1228         }
1229     }
1230
1231     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1232
1233     /**
1234      * Information about and control over application operations
1235      */
1236     final AppOpsService mAppOpsService;
1237
1238     /** Current sequencing integer of the configuration, for skipping old configurations. */
1239     private int mConfigurationSeq;
1240
1241     /**
1242      * Temp object used when global and/or display override configuration is updated. It is also
1243      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1244      * anyone...
1245      */
1246     private Configuration mTempConfig = new Configuration();
1247
1248     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1249             new UpdateConfigurationResult();
1250     private static final class UpdateConfigurationResult {
1251         // Configuration changes that were updated.
1252         int changes;
1253         // If the activity was relaunched to match the new configuration.
1254         boolean activityRelaunched;
1255
1256         void reset() {
1257             changes = 0;
1258             activityRelaunched = false;
1259         }
1260     }
1261
1262     boolean mSuppressResizeConfigChanges;
1263
1264     /**
1265      * Hardware-reported OpenGLES version.
1266      */
1267     final int GL_ES_VERSION;
1268
1269     /**
1270      * List of initialization arguments to pass to all processes when binding applications to them.
1271      * For example, references to the commonly used services.
1272      */
1273     HashMap<String, IBinder> mAppBindArgs;
1274     HashMap<String, IBinder> mIsolatedAppBindArgs;
1275
1276     /**
1277      * Temporary to avoid allocations.  Protected by main lock.
1278      */
1279     final StringBuilder mStringBuilder = new StringBuilder(256);
1280
1281     /**
1282      * Used to control how we initialize the service.
1283      */
1284     ComponentName mTopComponent;
1285     String mTopAction = Intent.ACTION_MAIN;
1286     String mTopData;
1287
1288     volatile boolean mProcessesReady = false;
1289     volatile boolean mSystemReady = false;
1290     volatile boolean mOnBattery = false;
1291     volatile int mFactoryTest;
1292
1293     @GuardedBy("this") boolean mBooting = false;
1294     @GuardedBy("this") boolean mCallFinishBooting = false;
1295     @GuardedBy("this") boolean mBootAnimationComplete = false;
1296     @GuardedBy("this") boolean mLaunchWarningShown = false;
1297     @GuardedBy("this") boolean mCheckedForSetup = false;
1298
1299     final Context mContext;
1300
1301     /**
1302      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1303      * change at runtime. Use mContext for non-UI purposes.
1304      */
1305     final Context mUiContext;
1306
1307     /**
1308      * The time at which we will allow normal application switches again,
1309      * after a call to {@link #stopAppSwitches()}.
1310      */
1311     long mAppSwitchesAllowedTime;
1312
1313     /**
1314      * This is set to true after the first switch after mAppSwitchesAllowedTime
1315      * is set; any switches after that will clear the time.
1316      */
1317     boolean mDidAppSwitch;
1318
1319     /**
1320      * Last time (in uptime) at which we checked for power usage.
1321      */
1322     long mLastPowerCheckUptime;
1323
1324     /**
1325      * Set while we are wanting to sleep, to prevent any
1326      * activities from being started/resumed.
1327      *
1328      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1329      *
1330      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1331      * while in the sleep state until there is a pending transition out of sleep, in which case
1332      * mSleeping is set to false, and remains false while awake.
1333      *
1334      * Whether mSleeping can quickly toggled between true/false without the device actually
1335      * display changing states is undefined.
1336      */
1337     private boolean mSleeping = false;
1338
1339     /**
1340      * The process state used for processes that are running the top activities.
1341      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1342      */
1343     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1344
1345     /**
1346      * Set while we are running a voice interaction.  This overrides
1347      * sleeping while it is active.
1348      */
1349     IVoiceInteractionSession mRunningVoice;
1350
1351     /**
1352      * For some direct access we need to power manager.
1353      */
1354     PowerManagerInternal mLocalPowerManager;
1355
1356     /**
1357      * We want to hold a wake lock while running a voice interaction session, since
1358      * this may happen with the screen off and we need to keep the CPU running to
1359      * be able to continue to interact with the user.
1360      */
1361     PowerManager.WakeLock mVoiceWakeLock;
1362
1363     /**
1364      * State of external calls telling us if the device is awake or asleep.
1365      */
1366     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1367
1368     /**
1369      * Set if we are shutting down the system, similar to sleeping.
1370      */
1371     boolean mShuttingDown = false;
1372
1373     /**
1374      * Current sequence id for oom_adj computation traversal.
1375      */
1376     int mAdjSeq = 0;
1377
1378     /**
1379      * Current sequence id for process LRU updating.
1380      */
1381     int mLruSeq = 0;
1382
1383     /**
1384      * Keep track of the non-cached/empty process we last found, to help
1385      * determine how to distribute cached/empty processes next time.
1386      */
1387     int mNumNonCachedProcs = 0;
1388
1389     /**
1390      * Keep track of the number of cached hidden procs, to balance oom adj
1391      * distribution between those and empty procs.
1392      */
1393     int mNumCachedHiddenProcs = 0;
1394
1395     /**
1396      * Keep track of the number of service processes we last found, to
1397      * determine on the next iteration which should be B services.
1398      */
1399     int mNumServiceProcs = 0;
1400     int mNewNumAServiceProcs = 0;
1401     int mNewNumServiceProcs = 0;
1402
1403     /**
1404      * Allow the current computed overall memory level of the system to go down?
1405      * This is set to false when we are killing processes for reasons other than
1406      * memory management, so that the now smaller process list will not be taken as
1407      * an indication that memory is tighter.
1408      */
1409     boolean mAllowLowerMemLevel = false;
1410
1411     /**
1412      * The last computed memory level, for holding when we are in a state that
1413      * processes are going away for other reasons.
1414      */
1415     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1416
1417     /**
1418      * The last total number of process we have, to determine if changes actually look
1419      * like a shrinking number of process due to lower RAM.
1420      */
1421     int mLastNumProcesses;
1422
1423     /**
1424      * The uptime of the last time we performed idle maintenance.
1425      */
1426     long mLastIdleTime = SystemClock.uptimeMillis();
1427
1428     /**
1429      * Total time spent with RAM that has been added in the past since the last idle time.
1430      */
1431     long mLowRamTimeSinceLastIdle = 0;
1432
1433     /**
1434      * If RAM is currently low, when that horrible situation started.
1435      */
1436     long mLowRamStartTime = 0;
1437
1438     /**
1439      * For reporting to battery stats the current top application.
1440      */
1441     private String mCurResumedPackage = null;
1442     private int mCurResumedUid = -1;
1443
1444     /**
1445      * For reporting to battery stats the apps currently running foreground
1446      * service.  The ProcessMap is package/uid tuples; each of these contain
1447      * an array of the currently foreground processes.
1448      */
1449     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1450             = new ProcessMap<ArrayList<ProcessRecord>>();
1451
1452     /**
1453      * Set if the systemServer made a call to enterSafeMode.
1454      */
1455     boolean mSafeMode;
1456
1457     /**
1458      * If true, we are running under a test environment so will sample PSS from processes
1459      * much more rapidly to try to collect better data when the tests are rapidly
1460      * running through apps.
1461      */
1462     boolean mTestPssMode = false;
1463
1464     String mDebugApp = null;
1465     boolean mWaitForDebugger = false;
1466     boolean mDebugTransient = false;
1467     String mOrigDebugApp = null;
1468     boolean mOrigWaitForDebugger = false;
1469     boolean mAlwaysFinishActivities = false;
1470     boolean mForceResizableActivities;
1471     /**
1472      * Flag that indicates if multi-window is enabled.
1473      *
1474      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1475      * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1476      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1477      * At least one of the forms of multi-window must be enabled in order for this flag to be
1478      * initialized to 'true'.
1479      *
1480      * @see #mSupportsSplitScreenMultiWindow
1481      * @see #mSupportsFreeformWindowManagement
1482      * @see #mSupportsPictureInPicture
1483      * @see #mSupportsMultiDisplay
1484      */
1485     boolean mSupportsMultiWindow;
1486     boolean mSupportsSplitScreenMultiWindow;
1487     boolean mSupportsFreeformWindowManagement;
1488     boolean mSupportsPictureInPicture;
1489     boolean mSupportsMultiDisplay;
1490     boolean mSupportsLeanbackOnly;
1491     IActivityController mController = null;
1492     boolean mControllerIsAMonkey = false;
1493     String mProfileApp = null;
1494     ProcessRecord mProfileProc = null;
1495     ProfilerInfo mProfilerInfo = null;
1496     int mProfileType = 0;
1497     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1498     String mMemWatchDumpProcName;
1499     String mMemWatchDumpFile;
1500     int mMemWatchDumpPid;
1501     int mMemWatchDumpUid;
1502     String mTrackAllocationApp = null;
1503     String mNativeDebuggingApp = null;
1504
1505     final long[] mTmpLong = new long[2];
1506
1507     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1508
1509     /**
1510      * A global counter for generating sequence numbers.
1511      * This value will be used when incrementing sequence numbers in individual uidRecords.
1512      *
1513      * Having a global counter ensures that seq numbers are monotonically increasing for a
1514      * particular uid even when the uidRecord is re-created.
1515      */
1516     @GuardedBy("this")
1517     @VisibleForTesting
1518     long mProcStateSeqCounter = 0;
1519
1520     private final Injector mInjector;
1521
1522     static final class ProcessChangeItem {
1523         static final int CHANGE_ACTIVITIES = 1<<0;
1524         int changes;
1525         int uid;
1526         int pid;
1527         int processState;
1528         boolean foregroundActivities;
1529     }
1530
1531     static final class UidObserverRegistration {
1532         final int uid;
1533         final String pkg;
1534         final int which;
1535         final int cutpoint;
1536
1537         final SparseIntArray lastProcStates;
1538
1539         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1540             uid = _uid;
1541             pkg = _pkg;
1542             which = _which;
1543             cutpoint = _cutpoint;
1544             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1545                 lastProcStates = new SparseIntArray();
1546             } else {
1547                 lastProcStates = null;
1548             }
1549         }
1550     }
1551
1552     final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1553
1554     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1555     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1556
1557     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1558     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1559
1560     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1561     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1562
1563     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1564     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1565
1566     OomAdjObserver mCurOomAdjObserver;
1567     int mCurOomAdjUid;
1568
1569     interface OomAdjObserver {
1570         void onOomAdjMessage(String msg);
1571     }
1572
1573     /**
1574      * Runtime CPU use collection thread.  This object's lock is used to
1575      * perform synchronization with the thread (notifying it to run).
1576      */
1577     final Thread mProcessCpuThread;
1578
1579     /**
1580      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1581      * Must acquire this object's lock when accessing it.
1582      * NOTE: this lock will be held while doing long operations (trawling
1583      * through all processes in /proc), so it should never be acquired by
1584      * any critical paths such as when holding the main activity manager lock.
1585      */
1586     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1587             MONITOR_THREAD_CPU_USAGE);
1588     final AtomicLong mLastCpuTime = new AtomicLong(0);
1589     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1590     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1591
1592     long mLastWriteTime = 0;
1593
1594     /**
1595      * Used to retain an update lock when the foreground activity is in
1596      * immersive mode.
1597      */
1598     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1599
1600     /**
1601      * Set to true after the system has finished booting.
1602      */
1603     boolean mBooted = false;
1604
1605     WindowManagerService mWindowManager;
1606     final ActivityThread mSystemThread;
1607
1608     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1609         final ProcessRecord mApp;
1610         final int mPid;
1611         final IApplicationThread mAppThread;
1612
1613         AppDeathRecipient(ProcessRecord app, int pid,
1614                 IApplicationThread thread) {
1615             if (DEBUG_ALL) Slog.v(
1616                 TAG, "New death recipient " + this
1617                 + " for thread " + thread.asBinder());
1618             mApp = app;
1619             mPid = pid;
1620             mAppThread = thread;
1621         }
1622
1623         @Override
1624         public void binderDied() {
1625             if (DEBUG_ALL) Slog.v(
1626                 TAG, "Death received in " + this
1627                 + " for thread " + mAppThread.asBinder());
1628             synchronized(ActivityManagerService.this) {
1629                 appDiedLocked(mApp, mPid, mAppThread, true);
1630             }
1631         }
1632     }
1633
1634     static final int SHOW_ERROR_UI_MSG = 1;
1635     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1636     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1637     static final int UPDATE_CONFIGURATION_MSG = 4;
1638     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1639     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1640     static final int SERVICE_TIMEOUT_MSG = 12;
1641     static final int UPDATE_TIME_ZONE = 13;
1642     static final int SHOW_UID_ERROR_UI_MSG = 14;
1643     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1644     static final int PROC_START_TIMEOUT_MSG = 20;
1645     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1646     static final int KILL_APPLICATION_MSG = 22;
1647     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1648     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1649     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1650     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1651     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1652     static final int CLEAR_DNS_CACHE_MSG = 28;
1653     static final int UPDATE_HTTP_PROXY_MSG = 29;
1654     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1655     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1656     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1657     static final int REPORT_MEM_USAGE_MSG = 33;
1658     static final int REPORT_USER_SWITCH_MSG = 34;
1659     static final int CONTINUE_USER_SWITCH_MSG = 35;
1660     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1661     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1662     static final int PERSIST_URI_GRANTS_MSG = 38;
1663     static final int REQUEST_ALL_PSS_MSG = 39;
1664     static final int START_PROFILES_MSG = 40;
1665     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1666     static final int SYSTEM_USER_START_MSG = 42;
1667     static final int SYSTEM_USER_CURRENT_MSG = 43;
1668     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1669     static final int FINISH_BOOTING_MSG = 45;
1670     static final int START_USER_SWITCH_UI_MSG = 46;
1671     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1672     static final int DISMISS_DIALOG_UI_MSG = 48;
1673     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1674     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1675     static final int DELETE_DUMPHEAP_MSG = 51;
1676     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1677     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1678     static final int REPORT_TIME_TRACKER_MSG = 54;
1679     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1680     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1681     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1682     static final int IDLE_UIDS_MSG = 58;
1683     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1684     static final int LOG_STACK_STATE = 60;
1685     static final int VR_MODE_CHANGE_MSG = 61;
1686     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1687     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1688     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1689     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1690     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1691     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1692     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1693     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1694     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1695     static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
1696     static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
1697     static final int START_USER_SWITCH_FG_MSG = 712;
1698     static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1699
1700     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1701     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1702     static final int FIRST_COMPAT_MODE_MSG = 300;
1703     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1704
1705     static ServiceThread sKillThread = null;
1706     static KillHandler sKillHandler = null;
1707
1708     CompatModeDialog mCompatModeDialog;
1709     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1710     long mLastMemUsageReportTime = 0;
1711
1712     /**
1713      * Flag whether the current user is a "monkey", i.e. whether
1714      * the UI is driven by a UI automation tool.
1715      */
1716     private boolean mUserIsMonkey;
1717
1718     /** Flag whether the device has a Recents UI */
1719     boolean mHasRecents;
1720
1721     /** The dimensions of the thumbnails in the Recents UI. */
1722     int mThumbnailWidth;
1723     int mThumbnailHeight;
1724     float mFullscreenThumbnailScale;
1725
1726     final ServiceThread mHandlerThread;
1727     final MainHandler mHandler;
1728     final Handler mUiHandler;
1729
1730     final ActivityManagerConstants mConstants;
1731
1732     PackageManagerInternal mPackageManagerInt;
1733
1734     // VoiceInteraction session ID that changes for each new request except when
1735     // being called for multiwindow assist in a single session.
1736     private int mViSessionId = 1000;
1737
1738     final boolean mPermissionReviewRequired;
1739
1740     private static String sTheRealBuildSerial = Build.UNKNOWN;
1741
1742     /**
1743      * Current global configuration information. Contains general settings for the entire system,
1744      * also corresponds to the merged configuration of the default display.
1745      */
1746     Configuration getGlobalConfiguration() {
1747         return mStackSupervisor.getConfiguration();
1748     }
1749
1750     final class KillHandler extends Handler {
1751         static final int KILL_PROCESS_GROUP_MSG = 4000;
1752
1753         public KillHandler(Looper looper) {
1754             super(looper, null, true);
1755         }
1756
1757         @Override
1758         public void handleMessage(Message msg) {
1759             switch (msg.what) {
1760                 case KILL_PROCESS_GROUP_MSG:
1761                 {
1762                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1763                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1764                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1765                 }
1766                 break;
1767
1768                 default:
1769                     super.handleMessage(msg);
1770             }
1771         }
1772     }
1773
1774     final class UiHandler extends Handler {
1775         public UiHandler() {
1776             super(com.android.server.UiThread.get().getLooper(), null, true);
1777         }
1778
1779         @Override
1780         public void handleMessage(Message msg) {
1781             switch (msg.what) {
1782             case SHOW_ERROR_UI_MSG: {
1783                 mAppErrors.handleShowAppErrorUi(msg);
1784                 ensureBootCompleted();
1785             } break;
1786             case SHOW_NOT_RESPONDING_UI_MSG: {
1787                 mAppErrors.handleShowAnrUi(msg);
1788                 ensureBootCompleted();
1789             } break;
1790             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1791                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1792                 synchronized (ActivityManagerService.this) {
1793                     ProcessRecord proc = (ProcessRecord) data.get("app");
1794                     if (proc == null) {
1795                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1796                         break;
1797                     }
1798                     if (proc.crashDialog != null) {
1799                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1800                         return;
1801                     }
1802                     AppErrorResult res = (AppErrorResult) data.get("result");
1803                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1804                         Dialog d = new StrictModeViolationDialog(mUiContext,
1805                                 ActivityManagerService.this, res, proc);
1806                         d.show();
1807                         proc.crashDialog = d;
1808                     } else {
1809                         // The device is asleep, so just pretend that the user
1810                         // saw a crash dialog and hit "force quit".
1811                         res.set(0);
1812                     }
1813                 }
1814                 ensureBootCompleted();
1815             } break;
1816             case SHOW_FACTORY_ERROR_UI_MSG: {
1817                 Dialog d = new FactoryErrorDialog(
1818                         mUiContext, msg.getData().getCharSequence("msg"));
1819                 d.show();
1820                 ensureBootCompleted();
1821             } break;
1822             case WAIT_FOR_DEBUGGER_UI_MSG: {
1823                 synchronized (ActivityManagerService.this) {
1824                     ProcessRecord app = (ProcessRecord)msg.obj;
1825                     if (msg.arg1 != 0) {
1826                         if (!app.waitedForDebugger) {
1827                             Dialog d = new AppWaitingForDebuggerDialog(
1828                                     ActivityManagerService.this,
1829                                     mUiContext, app);
1830                             app.waitDialog = d;
1831                             app.waitedForDebugger = true;
1832                             d.show();
1833                         }
1834                     } else {
1835                         if (app.waitDialog != null) {
1836                             app.waitDialog.dismiss();
1837                             app.waitDialog = null;
1838                         }
1839                     }
1840                 }
1841             } break;
1842             case SHOW_UID_ERROR_UI_MSG: {
1843                 if (mShowDialogs) {
1844                     AlertDialog d = new BaseErrorDialog(mUiContext);
1845                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1846                     d.setCancelable(false);
1847                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1848                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1849                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1850                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1851                     d.show();
1852                 }
1853             } break;
1854             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1855                 if (mShowDialogs) {
1856                     AlertDialog d = new BaseErrorDialog(mUiContext);
1857                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1858                     d.setCancelable(false);
1859                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1860                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1861                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1862                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1863                     d.show();
1864                 }
1865             } break;
1866             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1867                 synchronized (ActivityManagerService.this) {
1868                     ActivityRecord ar = (ActivityRecord) msg.obj;
1869                     if (mCompatModeDialog != null) {
1870                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1871                                 ar.info.applicationInfo.packageName)) {
1872                             return;
1873                         }
1874                         mCompatModeDialog.dismiss();
1875                         mCompatModeDialog = null;
1876                     }
1877                     if (ar != null && false) {
1878                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1879                                 ar.packageName)) {
1880                             int mode = mCompatModePackages.computeCompatModeLocked(
1881                                     ar.info.applicationInfo);
1882                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1883                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1884                                 mCompatModeDialog = new CompatModeDialog(
1885                                         ActivityManagerService.this, mUiContext,
1886                                         ar.info.applicationInfo);
1887                                 mCompatModeDialog.show();
1888                             }
1889                         }
1890                     }
1891                 }
1892                 break;
1893             }
1894             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1895                 synchronized (ActivityManagerService.this) {
1896                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1897                     if (mUnsupportedDisplaySizeDialog != null) {
1898                         mUnsupportedDisplaySizeDialog.dismiss();
1899                         mUnsupportedDisplaySizeDialog = null;
1900                     }
1901                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1902                             ar.packageName)) {
1903                         // TODO(multi-display): Show dialog on appropriate display.
1904                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1905                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1906                         mUnsupportedDisplaySizeDialog.show();
1907                     }
1908                 }
1909                 break;
1910             }
1911             case START_USER_SWITCH_UI_MSG: {
1912                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1913                 break;
1914             }
1915             case DISMISS_DIALOG_UI_MSG: {
1916                 final Dialog d = (Dialog) msg.obj;
1917                 d.dismiss();
1918                 break;
1919             }
1920             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1921                 dispatchProcessesChanged();
1922                 break;
1923             }
1924             case DISPATCH_PROCESS_DIED_UI_MSG: {
1925                 final int pid = msg.arg1;
1926                 final int uid = msg.arg2;
1927                 dispatchProcessDied(pid, uid);
1928                 break;
1929             }
1930             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1931                 dispatchUidsChanged();
1932             } break;
1933             case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1934                 dispatchOomAdjObserver((String)msg.obj);
1935             } break;
1936             case PUSH_TEMP_WHITELIST_UI_MSG: {
1937                 pushTempWhitelist();
1938             } break;
1939             }
1940         }
1941     }
1942
1943     final class MainHandler extends Handler {
1944         public MainHandler(Looper looper) {
1945             super(looper, null, true);
1946         }
1947
1948         @Override
1949         public void handleMessage(Message msg) {
1950             switch (msg.what) {
1951             case UPDATE_CONFIGURATION_MSG: {
1952                 final ContentResolver resolver = mContext.getContentResolver();
1953                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1954                         msg.arg1);
1955             } break;
1956             case GC_BACKGROUND_PROCESSES_MSG: {
1957                 synchronized (ActivityManagerService.this) {
1958                     performAppGcsIfAppropriateLocked();
1959                 }
1960             } break;
1961             case SERVICE_TIMEOUT_MSG: {
1962                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1963             } break;
1964             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1965                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1966             } break;
1967             case SERVICE_FOREGROUND_CRASH_MSG: {
1968                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1969             } break;
1970             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1971                 RemoteCallbackList<IResultReceiver> callbacks
1972                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1973                 int N = callbacks.beginBroadcast();
1974                 for (int i = 0; i < N; i++) {
1975                     try {
1976                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1977                     } catch (RemoteException e) {
1978                     }
1979                 }
1980                 callbacks.finishBroadcast();
1981             } break;
1982             case UPDATE_TIME_ZONE: {
1983                 synchronized (ActivityManagerService.this) {
1984                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1985                         ProcessRecord r = mLruProcesses.get(i);
1986                         if (r.thread != null) {
1987                             try {
1988                                 r.thread.updateTimeZone();
1989                             } catch (RemoteException ex) {
1990                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1991                             }
1992                         }
1993                     }
1994                 }
1995             } break;
1996             case CLEAR_DNS_CACHE_MSG: {
1997                 synchronized (ActivityManagerService.this) {
1998                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1999                         ProcessRecord r = mLruProcesses.get(i);
2000                         if (r.thread != null) {
2001                             try {
2002                                 r.thread.clearDnsCache();
2003                             } catch (RemoteException ex) {
2004                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2005                             }
2006                         }
2007                     }
2008                 }
2009             } break;
2010             case UPDATE_HTTP_PROXY_MSG: {
2011                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2012                 String host = "";
2013                 String port = "";
2014                 String exclList = "";
2015                 Uri pacFileUrl = Uri.EMPTY;
2016                 if (proxy != null) {
2017                     host = proxy.getHost();
2018                     port = Integer.toString(proxy.getPort());
2019                     exclList = proxy.getExclusionListAsString();
2020                     pacFileUrl = proxy.getPacFileUrl();
2021                 }
2022                 synchronized (ActivityManagerService.this) {
2023                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2024                         ProcessRecord r = mLruProcesses.get(i);
2025                         if (r.thread != null) {
2026                             try {
2027                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2028                             } catch (RemoteException ex) {
2029                                 Slog.w(TAG, "Failed to update http proxy for: " +
2030                                         r.info.processName);
2031                             }
2032                         }
2033                     }
2034                 }
2035             } break;
2036             case PROC_START_TIMEOUT_MSG: {
2037                 ProcessRecord app = (ProcessRecord)msg.obj;
2038                 synchronized (ActivityManagerService.this) {
2039                     processStartTimedOutLocked(app);
2040                 }
2041             } break;
2042             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2043                 ProcessRecord app = (ProcessRecord)msg.obj;
2044                 synchronized (ActivityManagerService.this) {
2045                     processContentProviderPublishTimedOutLocked(app);
2046                 }
2047             } break;
2048             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2049                 synchronized (ActivityManagerService.this) {
2050                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2051                 }
2052             } break;
2053             case KILL_APPLICATION_MSG: {
2054                 synchronized (ActivityManagerService.this) {
2055                     final int appId = msg.arg1;
2056                     final int userId = msg.arg2;
2057                     Bundle bundle = (Bundle)msg.obj;
2058                     String pkg = bundle.getString("pkg");
2059                     String reason = bundle.getString("reason");
2060                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2061                             false, userId, reason);
2062                 }
2063             } break;
2064             case FINALIZE_PENDING_INTENT_MSG: {
2065                 ((PendingIntentRecord)msg.obj).completeFinalize();
2066             } break;
2067             case POST_HEAVY_NOTIFICATION_MSG: {
2068                 INotificationManager inm = NotificationManager.getService();
2069                 if (inm == null) {
2070                     return;
2071                 }
2072
2073                 ActivityRecord root = (ActivityRecord)msg.obj;
2074                 ProcessRecord process = root.app;
2075                 if (process == null) {
2076                     return;
2077                 }
2078
2079                 try {
2080                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2081                     String text = mContext.getString(R.string.heavy_weight_notification,
2082                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2083                     Notification notification =
2084                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2085                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2086                             .setWhen(0)
2087                             .setOngoing(true)
2088                             .setTicker(text)
2089                             .setColor(mContext.getColor(
2090                                     com.android.internal.R.color.system_notification_accent_color))
2091                             .setContentTitle(text)
2092                             .setContentText(
2093                                     mContext.getText(R.string.heavy_weight_notification_detail))
2094                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2095                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2096                                     new UserHandle(root.userId)))
2097                             .build();
2098                     try {
2099                         inm.enqueueNotificationWithTag("android", "android", null,
2100                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2101                                 notification, root.userId);
2102                     } catch (RuntimeException e) {
2103                         Slog.w(ActivityManagerService.TAG,
2104                                 "Error showing notification for heavy-weight app", e);
2105                     } catch (RemoteException e) {
2106                     }
2107                 } catch (NameNotFoundException e) {
2108                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2109                 }
2110             } break;
2111             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2112                 INotificationManager inm = NotificationManager.getService();
2113                 if (inm == null) {
2114                     return;
2115                 }
2116                 try {
2117                     inm.cancelNotificationWithTag("android", null,
2118                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2119                 } catch (RuntimeException e) {
2120                     Slog.w(ActivityManagerService.TAG,
2121                             "Error canceling notification for service", e);
2122                 } catch (RemoteException e) {
2123                 }
2124             } break;
2125             case CHECK_EXCESSIVE_POWER_USE_MSG: {
2126                 synchronized (ActivityManagerService.this) {
2127                     checkExcessivePowerUsageLocked();
2128                     removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2129                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2130                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2131                 }
2132             } break;
2133             case REPORT_MEM_USAGE_MSG: {
2134                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2135                 Thread thread = new Thread() {
2136                     @Override public void run() {
2137                         reportMemUsage(memInfos);
2138                     }
2139                 };
2140                 thread.start();
2141                 break;
2142             }
2143             case START_USER_SWITCH_FG_MSG: {
2144                 mUserController.startUserInForeground(msg.arg1);
2145                 break;
2146             }
2147             case REPORT_USER_SWITCH_MSG: {
2148                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2149                 break;
2150             }
2151             case CONTINUE_USER_SWITCH_MSG: {
2152                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2153                 break;
2154             }
2155             case USER_SWITCH_TIMEOUT_MSG: {
2156                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2157                 break;
2158             }
2159             case IMMERSIVE_MODE_LOCK_MSG: {
2160                 final boolean nextState = (msg.arg1 != 0);
2161                 if (mUpdateLock.isHeld() != nextState) {
2162                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2163                             "Applying new update lock state '" + nextState
2164                             + "' for " + (ActivityRecord)msg.obj);
2165                     if (nextState) {
2166                         mUpdateLock.acquire();
2167                     } else {
2168                         mUpdateLock.release();
2169                     }
2170                 }
2171                 break;
2172             }
2173             case PERSIST_URI_GRANTS_MSG: {
2174                 writeGrantedUriPermissions();
2175                 break;
2176             }
2177             case REQUEST_ALL_PSS_MSG: {
2178                 synchronized (ActivityManagerService.this) {
2179                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2180                 }
2181                 break;
2182             }
2183             case START_PROFILES_MSG: {
2184                 synchronized (ActivityManagerService.this) {
2185                     mUserController.startProfilesLocked();
2186                 }
2187                 break;
2188             }
2189             case UPDATE_TIME_PREFERENCE_MSG: {
2190                 // The user's time format preference might have changed.
2191                 // For convenience we re-use the Intent extra values.
2192                 synchronized (ActivityManagerService.this) {
2193                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2194                         ProcessRecord r = mLruProcesses.get(i);
2195                         if (r.thread != null) {
2196                             try {
2197                                 r.thread.updateTimePrefs(msg.arg1);
2198                             } catch (RemoteException ex) {
2199                                 Slog.w(TAG, "Failed to update preferences for: "
2200                                         + r.info.processName);
2201                             }
2202                         }
2203                     }
2204                 }
2205                 break;
2206             }
2207             case SYSTEM_USER_START_MSG: {
2208                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2209                         Integer.toString(msg.arg1), msg.arg1);
2210                 mSystemServiceManager.startUser(msg.arg1);
2211                 break;
2212             }
2213             case SYSTEM_USER_UNLOCK_MSG: {
2214                 final int userId = msg.arg1;
2215                 mSystemServiceManager.unlockUser(userId);
2216                 synchronized (ActivityManagerService.this) {
2217                     mRecentTasks.loadUserRecentsLocked(userId);
2218                 }
2219                 if (userId == UserHandle.USER_SYSTEM) {
2220                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2221                 }
2222                 installEncryptionUnawareProviders(userId);
2223                 mUserController.finishUserUnlocked((UserState) msg.obj);
2224                 break;
2225             }
2226             case SYSTEM_USER_CURRENT_MSG: {
2227                 mBatteryStatsService.noteEvent(
2228                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2229                         Integer.toString(msg.arg2), msg.arg2);
2230                 mBatteryStatsService.noteEvent(
2231                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2232                         Integer.toString(msg.arg1), msg.arg1);
2233                 mSystemServiceManager.switchUser(msg.arg1);
2234                 break;
2235             }
2236             case ENTER_ANIMATION_COMPLETE_MSG: {
2237                 synchronized (ActivityManagerService.this) {
2238                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2239                     if (r != null && r.app != null && r.app.thread != null) {
2240                         try {
2241                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2242                         } catch (RemoteException e) {
2243                         }
2244                     }
2245                 }
2246                 break;
2247             }
2248             case FINISH_BOOTING_MSG: {
2249                 if (msg.arg1 != 0) {
2250                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2251                     finishBooting();
2252                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2253                 }
2254                 if (msg.arg2 != 0) {
2255                     enableScreenAfterBoot();
2256                 }
2257                 break;
2258             }
2259             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2260                 try {
2261                     Locale l = (Locale) msg.obj;
2262                     IBinder service = ServiceManager.getService("mount");
2263                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2264                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2265                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2266                 } catch (RemoteException e) {
2267                     Log.e(TAG, "Error storing locale for decryption UI", e);
2268                 }
2269                 break;
2270             }
2271             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2272                 final int uid = msg.arg1;
2273                 final byte[] firstPacket = (byte[]) msg.obj;
2274
2275                 synchronized (mPidsSelfLocked) {
2276                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2277                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2278                         if (p.uid == uid) {
2279                             try {
2280                                 p.thread.notifyCleartextNetwork(firstPacket);
2281                             } catch (RemoteException ignored) {
2282                             }
2283                         }
2284                     }
2285                 }
2286                 break;
2287             }
2288             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2289                 final String procName;
2290                 final int uid;
2291                 final long memLimit;
2292                 final String reportPackage;
2293                 synchronized (ActivityManagerService.this) {
2294                     procName = mMemWatchDumpProcName;
2295                     uid = mMemWatchDumpUid;
2296                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2297                     if (val == null) {
2298                         val = mMemWatchProcesses.get(procName, 0);
2299                     }
2300                     if (val != null) {
2301                         memLimit = val.first;
2302                         reportPackage = val.second;
2303                     } else {
2304                         memLimit = 0;
2305                         reportPackage = null;
2306                     }
2307                 }
2308                 if (procName == null) {
2309                     return;
2310                 }
2311
2312                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2313                         "Showing dump heap notification from " + procName + "/" + uid);
2314
2315                 INotificationManager inm = NotificationManager.getService();
2316                 if (inm == null) {
2317                     return;
2318                 }
2319
2320                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2321
2322
2323                 Intent deleteIntent = new Intent();
2324                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2325                 Intent intent = new Intent();
2326                 intent.setClassName("android", DumpHeapActivity.class.getName());
2327                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2328                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2329                 if (reportPackage != null) {
2330                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2331                 }
2332                 int userId = UserHandle.getUserId(uid);
2333                 Notification notification =
2334                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2335                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2336                         .setWhen(0)
2337                         .setOngoing(true)
2338                         .setAutoCancel(true)
2339                         .setTicker(text)
2340                         .setColor(mContext.getColor(
2341                                 com.android.internal.R.color.system_notification_accent_color))
2342                         .setContentTitle(text)
2343                         .setContentText(
2344                                 mContext.getText(R.string.dump_heap_notification_detail))
2345                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2346                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2347                                 new UserHandle(userId)))
2348                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2349                                 deleteIntent, 0, UserHandle.SYSTEM))
2350                         .build();
2351
2352                 try {
2353                     inm.enqueueNotificationWithTag("android", "android", null,
2354                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2355                             notification, userId);
2356                 } catch (RuntimeException e) {
2357                     Slog.w(ActivityManagerService.TAG,
2358                             "Error showing notification for dump heap", e);
2359                 } catch (RemoteException e) {
2360                 }
2361             } break;
2362             case DELETE_DUMPHEAP_MSG: {
2363                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2364                         null, DumpHeapActivity.JAVA_URI,
2365                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2366                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2367                         UserHandle.myUserId());
2368                 synchronized (ActivityManagerService.this) {
2369                     mMemWatchDumpFile = null;
2370                     mMemWatchDumpProcName = null;
2371                     mMemWatchDumpPid = -1;
2372                     mMemWatchDumpUid = -1;
2373                 }
2374             } break;
2375             case FOREGROUND_PROFILE_CHANGED_MSG: {
2376                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2377             } break;
2378             case REPORT_TIME_TRACKER_MSG: {
2379                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2380                 tracker.deliverResult(mContext);
2381             } break;
2382             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2383                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2384             } break;
2385             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2386                 mUserController.dispatchLockedBootComplete(msg.arg1);
2387             } break;
2388             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2389                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2390                 try {
2391                     connection.shutdown();
2392                 } catch (RemoteException e) {
2393                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2394                 }
2395                 // Only a UiAutomation can set this flag and now that
2396                 // it is finished we make sure it is reset to its default.
2397                 mUserIsMonkey = false;
2398             } break;
2399             case IDLE_UIDS_MSG: {
2400                 idleUids();
2401             } break;
2402             case VR_MODE_CHANGE_MSG: {
2403                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2404                     return;
2405                 }
2406                 synchronized (ActivityManagerService.this) {
2407                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2408                     mWindowManager.disableNonVrUi(disableNonVrUi);
2409                     if (disableNonVrUi) {
2410                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2411                         // then remove the pinned stack.
2412                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2413                                 PINNED_STACK_ID);
2414                         if (pinnedStack != null) {
2415                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2416                         }
2417                     }
2418                 }
2419             } break;
2420             case DISPATCH_SCREEN_AWAKE_MSG: {
2421                 final boolean isAwake = msg.arg1 != 0;
2422                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2423                     mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2424                 }
2425             } break;
2426             case DISPATCH_SCREEN_KEYGUARD_MSG: {
2427                 final boolean isShowing = msg.arg1 != 0;
2428                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2429                     mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2430                 }
2431             } break;
2432             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2433                 synchronized (ActivityManagerService.this) {
2434                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2435                         ProcessRecord r = mLruProcesses.get(i);
2436                         if (r.thread != null) {
2437                             try {
2438                                 r.thread.handleTrustStorageUpdate();
2439                             } catch (RemoteException ex) {
2440                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2441                                         r.info.processName);
2442                             }
2443                         }
2444                     }
2445                 }
2446             } break;
2447             }
2448         }
2449     };
2450
2451     static final int COLLECT_PSS_BG_MSG = 1;
2452
2453     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2454         @Override
2455         public void handleMessage(Message msg) {
2456             switch (msg.what) {
2457             case COLLECT_PSS_BG_MSG: {
2458                 long start = SystemClock.uptimeMillis();
2459                 MemInfoReader memInfo = null;
2460                 synchronized (ActivityManagerService.this) {
2461                     if (mFullPssPending) {
2462                         mFullPssPending = false;
2463                         memInfo = new MemInfoReader();
2464                     }
2465                 }
2466                 if (memInfo != null) {
2467                     updateCpuStatsNow();
2468                     long nativeTotalPss = 0;
2469                     final List<ProcessCpuTracker.Stats> stats;
2470                     synchronized (mProcessCpuTracker) {
2471                         stats = mProcessCpuTracker.getStats( (st)-> {
2472                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2473                         });
2474                     }
2475                     final int N = stats.size();
2476                     for (int j = 0; j < N; j++) {
2477                         synchronized (mPidsSelfLocked) {
2478                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2479                                 // This is one of our own processes; skip it.
2480                                 continue;
2481                             }
2482                         }
2483                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2484                     }
2485                     memInfo.readMemInfo();
2486                     synchronized (ActivityManagerService.this) {
2487                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2488                                 + (SystemClock.uptimeMillis()-start) + "ms");
2489                         final long cachedKb = memInfo.getCachedSizeKb();
2490                         final long freeKb = memInfo.getFreeSizeKb();
2491                         final long zramKb = memInfo.getZramTotalSizeKb();
2492                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2493                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2494                                 kernelKb*1024, nativeTotalPss*1024);
2495                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2496                                 nativeTotalPss);
2497                     }
2498                 }
2499
2500                 int num = 0;
2501                 long[] tmp = new long[2];
2502                 do {
2503                     ProcessRecord proc;
2504                     int procState;
2505                     int pid;
2506                     long lastPssTime;
2507                     synchronized (ActivityManagerService.this) {
2508                         if (mPendingPssProcesses.size() <= 0) {
2509                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2510                                     "Collected PSS of " + num + " processes in "
2511                                     + (SystemClock.uptimeMillis() - start) + "ms");
2512                             mPendingPssProcesses.clear();
2513                             return;
2514                         }
2515                         proc = mPendingPssProcesses.remove(0);
2516                         procState = proc.pssProcState;
2517                         lastPssTime = proc.lastPssTime;
2518                         if (proc.thread != null && procState == proc.setProcState
2519                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2520                                         < SystemClock.uptimeMillis()) {
2521                             pid = proc.pid;
2522                         } else {
2523                             proc = null;
2524                             pid = 0;
2525                         }
2526                     }
2527                     if (proc != null) {
2528                         long pss = Debug.getPss(pid, tmp, null);
2529                         synchronized (ActivityManagerService.this) {
2530                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2531                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2532                                 num++;
2533                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2534                                         SystemClock.uptimeMillis());
2535                             }
2536                         }
2537                     }
2538                 } while (true);
2539             }
2540             }
2541         }
2542     };
2543
2544     public void setSystemProcess() {
2545         try {
2546             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2547             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2548             ServiceManager.addService("meminfo", new MemBinder(this));
2549             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2550             ServiceManager.addService("dbinfo", new DbBinder(this));
2551             if (MONITOR_CPU_USAGE) {
2552                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2553             }
2554             ServiceManager.addService("permission", new PermissionController(this));
2555             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2556
2557             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2558                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2559             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2560
2561             synchronized (this) {
2562                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2563                 app.persistent = true;
2564                 app.pid = MY_PID;
2565                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2566                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2567                 synchronized (mPidsSelfLocked) {
2568                     mPidsSelfLocked.put(app.pid, app);
2569                 }
2570                 updateLruProcessLocked(app, false, null);
2571                 updateOomAdjLocked();
2572             }
2573         } catch (PackageManager.NameNotFoundException e) {
2574             throw new RuntimeException(
2575                     "Unable to find android system package", e);
2576         }
2577     }
2578
2579     public void setWindowManager(WindowManagerService wm) {
2580         mWindowManager = wm;
2581         mStackSupervisor.setWindowManager(wm);
2582         mActivityStarter.setWindowManager(wm);
2583     }
2584
2585     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2586         mUsageStatsService = usageStatsManager;
2587     }
2588
2589     public void startObservingNativeCrashes() {
2590         final NativeCrashListener ncl = new NativeCrashListener(this);
2591         ncl.start();
2592     }
2593
2594     public IAppOpsService getAppOpsService() {
2595         return mAppOpsService;
2596     }
2597
2598     static class MemBinder extends Binder {
2599         ActivityManagerService mActivityManagerService;
2600         MemBinder(ActivityManagerService activityManagerService) {
2601             mActivityManagerService = activityManagerService;
2602         }
2603
2604         @Override
2605         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2606             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2607                     "meminfo", pw)) return;
2608             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2609         }
2610     }
2611
2612     static class GraphicsBinder extends Binder {
2613         ActivityManagerService mActivityManagerService;
2614         GraphicsBinder(ActivityManagerService activityManagerService) {
2615             mActivityManagerService = activityManagerService;
2616         }
2617
2618         @Override
2619         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2620             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2621                     "gfxinfo", pw)) return;
2622             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2623         }
2624     }
2625
2626     static class DbBinder extends Binder {
2627         ActivityManagerService mActivityManagerService;
2628         DbBinder(ActivityManagerService activityManagerService) {
2629             mActivityManagerService = activityManagerService;
2630         }
2631
2632         @Override
2633         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2634             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2635                     "dbinfo", pw)) return;
2636             mActivityManagerService.dumpDbInfo(fd, pw, args);
2637         }
2638     }
2639
2640     static class CpuBinder extends Binder {
2641         ActivityManagerService mActivityManagerService;
2642         CpuBinder(ActivityManagerService activityManagerService) {
2643             mActivityManagerService = activityManagerService;
2644         }
2645
2646         @Override
2647         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2648             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2649                     "cpuinfo", pw)) return;
2650             synchronized (mActivityManagerService.mProcessCpuTracker) {
2651                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2652                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2653                         SystemClock.uptimeMillis()));
2654             }
2655         }
2656     }
2657
2658     public static final class Lifecycle extends SystemService {
2659         private final ActivityManagerService mService;
2660
2661         public Lifecycle(Context context) {
2662             super(context);
2663             mService = new ActivityManagerService(context);
2664         }
2665
2666         @Override
2667         public void onStart() {
2668             mService.start();
2669         }
2670
2671         @Override
2672         public void onCleanupUser(int userId) {
2673             mService.mBatteryStatsService.onCleanupUser(userId);
2674         }
2675
2676         public ActivityManagerService getService() {
2677             return mService;
2678         }
2679     }
2680
2681     @VisibleForTesting
2682     public ActivityManagerService(Injector injector) {
2683         mInjector = injector;
2684         mContext = mInjector.getContext();
2685         mUiContext = null;
2686         GL_ES_VERSION = 0;
2687         mActivityStarter = null;
2688         mAppErrors = null;
2689         mAppOpsService = mInjector.getAppOpsService(null, null);
2690         mBatteryStatsService = null;
2691         mCompatModePackages = null;
2692         mConstants = null;
2693         mGrantFile = null;
2694         mHandler = null;
2695         mHandlerThread = null;
2696         mIntentFirewall = null;
2697         mKeyguardController = null;
2698         mPermissionReviewRequired = false;
2699         mProcessCpuThread = null;
2700         mProcessStats = null;
2701         mProviderMap = null;
2702         mRecentTasks = null;
2703         mServices = null;
2704         mStackSupervisor = null;
2705         mSystemThread = null;
2706         mTaskChangeNotificationController = null;
2707         mUiHandler = injector.getUiHandler(null);
2708         mUserController = null;
2709         mVrController = null;
2710     }
2711
2712     // Note: This method is invoked on the main thread but may need to attach various
2713     // handlers to other threads.  So take care to be explicit about the looper.
2714     public ActivityManagerService(Context systemContext) {
2715         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2716         mInjector = new Injector();
2717         mContext = systemContext;
2718
2719         mFactoryTest = FactoryTest.getMode();
2720         mSystemThread = ActivityThread.currentActivityThread();
2721         mUiContext = mSystemThread.getSystemUiContext();
2722
2723         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2724
2725         mPermissionReviewRequired = mContext.getResources().getBoolean(
2726                 com.android.internal.R.bool.config_permissionReviewRequired);
2727
2728         mHandlerThread = new ServiceThread(TAG,
2729                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2730         mHandlerThread.start();
2731         mHandler = new MainHandler(mHandlerThread.getLooper());
2732         mUiHandler = mInjector.getUiHandler(this);
2733
2734         mConstants = new ActivityManagerConstants(this, mHandler);
2735
2736         /* static; one-time init here */
2737         if (sKillHandler == null) {
2738             sKillThread = new ServiceThread(TAG + ":kill",
2739                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2740             sKillThread.start();
2741             sKillHandler = new KillHandler(sKillThread.getLooper());
2742         }
2743
2744         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2745                 "foreground", BROADCAST_FG_TIMEOUT, false);
2746         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2747                 "background", BROADCAST_BG_TIMEOUT, true);
2748         mBroadcastQueues[0] = mFgBroadcastQueue;
2749         mBroadcastQueues[1] = mBgBroadcastQueue;
2750
2751         mServices = new ActiveServices(this);
2752         mProviderMap = new ProviderMap(this);
2753         mAppErrors = new AppErrors(mUiContext, this);
2754
2755         // TODO: Move creation of battery stats service outside of activity manager service.
2756         File dataDir = Environment.getDataDirectory();
2757         File systemDir = new File(dataDir, "system");
2758         systemDir.mkdirs();
2759         mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2760         mBatteryStatsService.getActiveStatistics().readLocked();
2761         mBatteryStatsService.scheduleWriteToDisk();
2762         mOnBattery = DEBUG_POWER ? true
2763                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2764         mBatteryStatsService.getActiveStatistics().setCallback(this);
2765
2766         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2767
2768         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2769         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2770                 new IAppOpsCallback.Stub() {
2771                     @Override public void opChanged(int op, int uid, String packageName) {
2772                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2773                             if (mAppOpsService.checkOperation(op, uid, packageName)
2774                                     != AppOpsManager.MODE_ALLOWED) {
2775                                 runInBackgroundDisabled(uid);
2776                             }
2777                         }
2778                     }
2779                 });
2780
2781         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2782
2783         mUserController = new UserController(this);
2784
2785         mVrController = new VrController(this);
2786
2787         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2788             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2789
2790         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2791             mUseFifoUiScheduling = true;
2792         }
2793
2794         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2795         mTempConfig.setToDefaults();
2796         mTempConfig.setLocales(LocaleList.getDefault());
2797         mConfigurationSeq = mTempConfig.seq = 1;
2798         mStackSupervisor = createStackSupervisor();
2799         mStackSupervisor.onConfigurationChanged(mTempConfig);
2800         mKeyguardController = mStackSupervisor.mKeyguardController;
2801         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2802         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2803         mTaskChangeNotificationController =
2804                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2805         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2806         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2807
2808         mProcessCpuThread = new Thread("CpuTracker") {
2809             @Override
2810             public void run() {
2811                 synchronized (mProcessCpuTracker) {
2812                     mProcessCpuInitLatch.countDown();
2813                     mProcessCpuTracker.init();
2814                 }
2815                 while (true) {
2816                     try {
2817                         try {
2818                             synchronized(this) {
2819                                 final long now = SystemClock.uptimeMillis();
2820                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2821                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2822                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2823                                 //        + ", write delay=" + nextWriteDelay);
2824                                 if (nextWriteDelay < nextCpuDelay) {
2825                                     nextCpuDelay = nextWriteDelay;
2826                                 }
2827                                 if (nextCpuDelay > 0) {
2828                                     mProcessCpuMutexFree.set(true);
2829                                     this.wait(nextCpuDelay);
2830                                 }
2831                             }
2832                         } catch (InterruptedException e) {
2833                         }
2834                         updateCpuStatsNow();
2835                     } catch (Exception e) {
2836                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2837                     }
2838                 }
2839             }
2840         };
2841
2842         Watchdog.getInstance().addMonitor(this);
2843         Watchdog.getInstance().addThread(mHandler);
2844     }
2845
2846     protected ActivityStackSupervisor createStackSupervisor() {
2847         return new ActivityStackSupervisor(this, mHandler.getLooper());
2848     }
2849
2850     public void setSystemServiceManager(SystemServiceManager mgr) {
2851         mSystemServiceManager = mgr;
2852     }
2853
2854     public void setInstaller(Installer installer) {
2855         mInstaller = installer;
2856     }
2857
2858     private void start() {
2859         removeAllProcessGroups();
2860         mProcessCpuThread.start();
2861
2862         mBatteryStatsService.publish();
2863         mAppOpsService.publish(mContext);
2864         Slog.d("AppOps", "AppOpsService published");
2865         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2866         // Wait for the synchronized block started in mProcessCpuThread,
2867         // so that any other acccess to mProcessCpuTracker from main thread
2868         // will be blocked during mProcessCpuTracker initialization.
2869         try {
2870             mProcessCpuInitLatch.await();
2871         } catch (InterruptedException e) {
2872             Slog.wtf(TAG, "Interrupted wait during start", e);
2873             Thread.currentThread().interrupt();
2874             throw new IllegalStateException("Interrupted wait during start");
2875         }
2876     }
2877
2878     void onUserStoppedLocked(int userId) {
2879         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2880     }
2881
2882     public void initPowerManagement() {
2883         mStackSupervisor.initPowerManagement();
2884         mBatteryStatsService.initPowerManagement();
2885         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2886         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2887         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2888         mVoiceWakeLock.setReferenceCounted(false);
2889     }
2890
2891     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2892         if (mBackgroundLaunchBroadcasts == null) {
2893             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2894         }
2895         return mBackgroundLaunchBroadcasts;
2896     }
2897
2898     @Override
2899     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2900             throws RemoteException {
2901         if (code == SYSPROPS_TRANSACTION) {
2902             // We need to tell all apps about the system property change.
2903             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2904             synchronized(this) {
2905                 final int NP = mProcessNames.getMap().size();
2906                 for (int ip=0; ip<NP; ip++) {
2907                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2908                     final int NA = apps.size();
2909                     for (int ia=0; ia<NA; ia++) {
2910                         ProcessRecord app = apps.valueAt(ia);
2911                         if (app.thread != null) {
2912                             procs.add(app.thread.asBinder());
2913                         }
2914                     }
2915                 }
2916             }
2917
2918             int N = procs.size();
2919             for (int i=0; i<N; i++) {
2920                 Parcel data2 = Parcel.obtain();
2921                 try {
2922                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2923                             Binder.FLAG_ONEWAY);
2924                 } catch (RemoteException e) {
2925                 }
2926                 data2.recycle();
2927             }
2928         }
2929         try {
2930             return super.onTransact(code, data, reply, flags);
2931         } catch (RuntimeException e) {
2932             // The activity manager only throws security exceptions, so let's
2933             // log all others.
2934             if (!(e instanceof SecurityException)) {
2935                 Slog.wtf(TAG, "Activity Manager Crash."
2936                         + " UID:" + Binder.getCallingUid()
2937                         + " PID:" + Binder.getCallingPid()
2938                         + " TRANS:" + code, e);
2939             }
2940             throw e;
2941         }
2942     }
2943
2944     void updateCpuStats() {
2945         final long now = SystemClock.uptimeMillis();
2946         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2947             return;
2948         }
2949         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2950             synchronized (mProcessCpuThread) {
2951                 mProcessCpuThread.notify();
2952             }
2953         }
2954     }
2955
2956     void updateCpuStatsNow() {
2957         synchronized (mProcessCpuTracker) {
2958             mProcessCpuMutexFree.set(false);
2959             final long now = SystemClock.uptimeMillis();
2960             boolean haveNewCpuStats = false;
2961
2962             if (MONITOR_CPU_USAGE &&
2963                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2964                 mLastCpuTime.set(now);
2965                 mProcessCpuTracker.update();
2966                 if (mProcessCpuTracker.hasGoodLastStats()) {
2967                     haveNewCpuStats = true;
2968                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2969                     //Slog.i(TAG, "Total CPU usage: "
2970                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2971
2972                     // Slog the cpu usage if the property is set.
2973                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2974                         int user = mProcessCpuTracker.getLastUserTime();
2975                         int system = mProcessCpuTracker.getLastSystemTime();
2976                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2977                         int irq = mProcessCpuTracker.getLastIrqTime();
2978                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2979                         int idle = mProcessCpuTracker.getLastIdleTime();
2980
2981                         int total = user + system + iowait + irq + softIrq + idle;
2982                         if (total == 0) total = 1;
2983
2984                         EventLog.writeEvent(EventLogTags.CPU,
2985                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2986                                 (user * 100) / total,
2987                                 (system * 100) / total,
2988                                 (iowait * 100) / total,
2989                                 (irq * 100) / total,
2990                                 (softIrq * 100) / total);
2991                     }
2992                 }
2993             }
2994
2995             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2996             synchronized(bstats) {
2997                 synchronized(mPidsSelfLocked) {
2998                     if (haveNewCpuStats) {
2999                         if (bstats.startAddingCpuLocked()) {
3000                             int totalUTime = 0;
3001                             int totalSTime = 0;
3002                             final int N = mProcessCpuTracker.countStats();
3003                             for (int i=0; i<N; i++) {
3004                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3005                                 if (!st.working) {
3006                                     continue;
3007                                 }
3008                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3009                                 totalUTime += st.rel_utime;
3010                                 totalSTime += st.rel_stime;
3011                                 if (pr != null) {
3012                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3013                                     if (ps == null || !ps.isActive()) {
3014                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3015                                                 pr.info.uid, pr.processName);
3016                                     }
3017                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3019                                     if (pr.lastCpuTime == 0) {
3020                                         pr.lastCpuTime = pr.curCpuTime;
3021                                     }
3022                                 } else {
3023                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3024                                     if (ps == null || !ps.isActive()) {
3025                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3026                                                 bstats.mapUid(st.uid), st.name);
3027                                     }
3028                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3029                                 }
3030                             }
3031                             final int userTime = mProcessCpuTracker.getLastUserTime();
3032                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3033                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3034                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3035                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3036                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3037                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3038                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3039                         }
3040                     }
3041                 }
3042
3043                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3044                     mLastWriteTime = now;
3045                     mBatteryStatsService.scheduleWriteToDisk();
3046                 }
3047             }
3048         }
3049     }
3050
3051     @Override
3052     public void batteryNeedsCpuUpdate() {
3053         updateCpuStatsNow();
3054     }
3055
3056     @Override
3057     public void batteryPowerChanged(boolean onBattery) {
3058         // When plugging in, update the CPU stats first before changing
3059         // the plug state.
3060         updateCpuStatsNow();
3061         synchronized (this) {
3062             synchronized(mPidsSelfLocked) {
3063                 mOnBattery = DEBUG_POWER ? true : onBattery;
3064             }
3065         }
3066     }
3067
3068     @Override
3069     public void batterySendBroadcast(Intent intent) {
3070         synchronized (this) {
3071             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3072                     AppOpsManager.OP_NONE, null, false, false,
3073                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3074         }
3075     }
3076
3077     /**
3078      * Initialize the application bind args. These are passed to each
3079      * process when the bindApplication() IPC is sent to the process. They're
3080      * lazily setup to make sure the services are running when they're asked for.
3081      */
3082     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3083         // Isolated processes won't get this optimization, so that we don't
3084         // violate the rules about which services they have access to.
3085         if (isolated) {
3086             if (mIsolatedAppBindArgs == null) {
3087                 mIsolatedAppBindArgs = new HashMap<>();
3088                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3089             }
3090             return mIsolatedAppBindArgs;
3091         }
3092
3093         if (mAppBindArgs == null) {
3094             mAppBindArgs = new HashMap<>();
3095
3096             // Setup the application init args
3097             mAppBindArgs.put("package", ServiceManager.getService("package"));
3098             mAppBindArgs.put("window", ServiceManager.getService("window"));
3099             mAppBindArgs.put(Context.ALARM_SERVICE,
3100                     ServiceManager.getService(Context.ALARM_SERVICE));
3101         }
3102         return mAppBindArgs;
3103     }
3104
3105     /**
3106      * Update AMS states when an activity is resumed. This should only be called by
3107      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3108      */
3109     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3110         final TaskRecord task = r.getTask();
3111         if (task.isApplicationTask()) {
3112             if (mCurAppTimeTracker != r.appTimeTracker) {
3113                 // We are switching app tracking.  Complete the current one.
3114                 if (mCurAppTimeTracker != null) {
3115                     mCurAppTimeTracker.stop();
3116                     mHandler.obtainMessage(
3117                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3118                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3119                     mCurAppTimeTracker = null;
3120                 }
3121                 if (r.appTimeTracker != null) {
3122                     mCurAppTimeTracker = r.appTimeTracker;
3123                     startTimeTrackingFocusedActivityLocked();
3124                 }
3125             } else {
3126                 startTimeTrackingFocusedActivityLocked();
3127             }
3128         } else {
3129             r.appTimeTracker = null;
3130         }
3131         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3132         // TODO: Probably not, because we don't want to resume voice on switching
3133         // back to this activity
3134         if (task.voiceInteractor != null) {
3135             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3136         } else {
3137             finishRunningVoiceLocked();
3138
3139             if (mLastResumedActivity != null) {
3140                 final IVoiceInteractionSession session;
3141
3142                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3143                 if (lastResumedActivityTask != null
3144                         && lastResumedActivityTask.voiceSession != null) {
3145                     session = lastResumedActivityTask.voiceSession;
3146                 } else {
3147                     session = mLastResumedActivity.voiceSession;
3148                 }
3149
3150                 if (session != null) {
3151                     // We had been in a voice interaction session, but now focused has
3152                     // move to something different.  Just finish the session, we can't
3153                     // return to it and retain the proper state and synchronization with
3154                     // the voice interaction service.
3155                     finishVoiceTask(session);
3156                 }
3157             }
3158         }
3159
3160         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3161             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3162             mHandler.obtainMessage(
3163                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3164         }
3165         mLastResumedActivity = r;
3166
3167         mWindowManager.setFocusedApp(r.appToken, true);
3168
3169         applyUpdateLockStateLocked(r);
3170         applyUpdateVrModeLocked(r);
3171
3172         EventLogTags.writeAmSetResumedActivity(
3173                 r == null ? -1 : r.userId,
3174                 r == null ? "NULL" : r.shortComponentName,
3175                 reason);
3176     }
3177
3178     @Override
3179     public void setFocusedStack(int stackId) {
3180         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3181         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3182         final long callingId = Binder.clearCallingIdentity();
3183         try {
3184             synchronized (this) {
3185                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3186                 if (stack == null) {
3187                     return;
3188                 }
3189                 final ActivityRecord r = stack.topRunningActivityLocked();
3190                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3191                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3192                 }
3193             }
3194         } finally {
3195             Binder.restoreCallingIdentity(callingId);
3196         }
3197     }
3198
3199     @Override
3200     public void setFocusedTask(int taskId) {
3201         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3202         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3203         final long callingId = Binder.clearCallingIdentity();
3204         try {
3205             synchronized (this) {
3206                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3207                 if (task == null) {
3208                     return;
3209                 }
3210                 final ActivityRecord r = task.topRunningActivityLocked();
3211                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3212                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3213                 }
3214             }
3215         } finally {
3216             Binder.restoreCallingIdentity(callingId);
3217         }
3218     }
3219
3220     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3221     @Override
3222     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3223         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3224         mTaskChangeNotificationController.registerTaskStackListener(listener);
3225     }
3226
3227     /**
3228      * Unregister a task stack listener so that it stops receiving callbacks.
3229      */
3230     @Override
3231     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3232          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3233          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3234      }
3235
3236     @Override
3237     public void notifyActivityDrawn(IBinder token) {
3238         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3239         synchronized (this) {
3240             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3241             if (r != null) {
3242                 r.getStack().notifyActivityDrawnLocked(r);
3243             }
3244         }
3245     }
3246
3247     final void applyUpdateLockStateLocked(ActivityRecord r) {
3248         // Modifications to the UpdateLock state are done on our handler, outside
3249         // the activity manager's locks.  The new state is determined based on the
3250         // state *now* of the relevant activity record.  The object is passed to
3251         // the handler solely for logging detail, not to be consulted/modified.
3252         final boolean nextState = r != null && r.immersive;
3253         mHandler.sendMessage(
3254                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3255     }
3256
3257     final void applyUpdateVrModeLocked(ActivityRecord r) {
3258         // VR apps are expected to run in a main display. If an app is turning on VR for
3259         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3260         // fullscreen stack before enabling VR Mode.
3261         // TODO: The goal of this code is to keep the VR app on the main display. When the
3262         // stack implementation changes in the future, keep in mind that the use of the fullscreen
3263         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3264         // option would be a better choice here.
3265         if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3266             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3267                     + " to main stack for VR");
3268             moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3269         }
3270         mHandler.sendMessage(
3271                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3272     }
3273
3274     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3275         Message msg = Message.obtain();
3276         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3277         msg.obj = r.getTask().askedCompatMode ? null : r;
3278         mUiHandler.sendMessage(msg);
3279     }
3280
3281     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3282         final Configuration globalConfig = getGlobalConfiguration();
3283         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3284                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3285             final Message msg = Message.obtain();
3286             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3287             msg.obj = r;
3288             mUiHandler.sendMessage(msg);
3289         }
3290     }
3291
3292     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3293             String what, Object obj, ProcessRecord srcApp) {
3294         app.lastActivityTime = now;
3295
3296         if (app.activities.size() > 0) {
3297             // Don't want to touch dependent processes that are hosting activities.
3298             return index;
3299         }
3300
3301         int lrui = mLruProcesses.lastIndexOf(app);
3302         if (lrui < 0) {
3303             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3304                     + what + " " + obj + " from " + srcApp);
3305             return index;
3306         }
3307
3308         if (lrui >= index) {
3309             // Don't want to cause this to move dependent processes *back* in the
3310             // list as if they were less frequently used.
3311             return index;
3312         }
3313
3314         if (lrui >= mLruProcessActivityStart) {
3315             // Don't want to touch dependent processes that are hosting activities.
3316             return index;
3317         }
3318
3319         mLruProcesses.remove(lrui);
3320         if (index > 0) {
3321             index--;
3322         }
3323         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3324                 + " in LRU list: " + app);
3325         mLruProcesses.add(index, app);
3326         return index;
3327     }
3328
3329     static void killProcessGroup(int uid, int pid) {
3330         if (sKillHandler != null) {
3331             sKillHandler.sendMessage(
3332                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3333         } else {
3334             Slog.w(TAG, "Asked to kill process group before system bringup!");
3335             Process.killProcessGroup(uid, pid);
3336         }
3337     }
3338
3339     final void removeLruProcessLocked(ProcessRecord app) {
3340         int lrui = mLruProcesses.lastIndexOf(app);
3341         if (lrui >= 0) {
3342             if (!app.killed) {
3343                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3344                 killProcessQuiet(app.pid);
3345                 killProcessGroup(app.uid, app.pid);
3346             }
3347             if (lrui <= mLruProcessActivityStart) {
3348                 mLruProcessActivityStart--;
3349             }
3350             if (lrui <= mLruProcessServiceStart) {
3351                 mLruProcessServiceStart--;
3352             }
3353             mLruProcesses.remove(lrui);
3354         }
3355     }
3356
3357     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3358             ProcessRecord client) {
3359         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3360                 || app.treatLikeActivity;
3361         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3362         if (!activityChange && hasActivity) {
3363             // The process has activities, so we are only allowing activity-based adjustments
3364             // to move it.  It should be kept in the front of the list with other
3365             // processes that have activities, and we don't want those to change their
3366             // order except due to activity operations.
3367             return;
3368         }
3369
3370         mLruSeq++;
3371         final long now = SystemClock.uptimeMillis();
3372         app.lastActivityTime = now;
3373
3374         // First a quick reject: if the app is already at the position we will
3375         // put it, then there is nothing to do.
3376         if (hasActivity) {
3377             final int N = mLruProcesses.size();
3378             if (N > 0 && mLruProcesses.get(N-1) == app) {
3379                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3380                 return;
3381             }
3382         } else {
3383             if (mLruProcessServiceStart > 0
3384                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3385                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3386                 return;
3387             }
3388         }
3389
3390         int lrui = mLruProcesses.lastIndexOf(app);
3391
3392         if (app.persistent && lrui >= 0) {
3393             // We don't care about the position of persistent processes, as long as
3394             // they are in the list.
3395             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3396             return;
3397         }
3398
3399         /* In progress: compute new position first, so we can avoid doing work
3400            if the process is not actually going to move.  Not yet working.
3401         int addIndex;
3402         int nextIndex;
3403         boolean inActivity = false, inService = false;
3404         if (hasActivity) {
3405             // Process has activities, put it at the very tipsy-top.
3406             addIndex = mLruProcesses.size();
3407             nextIndex = mLruProcessServiceStart;
3408             inActivity = true;
3409         } else if (hasService) {
3410             // Process has services, put it at the top of the service list.
3411             addIndex = mLruProcessActivityStart;
3412             nextIndex = mLruProcessServiceStart;
3413             inActivity = true;
3414             inService = true;
3415         } else  {
3416             // Process not otherwise of interest, it goes to the top of the non-service area.
3417             addIndex = mLruProcessServiceStart;
3418             if (client != null) {
3419                 int clientIndex = mLruProcesses.lastIndexOf(client);
3420                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3421                         + app);
3422                 if (clientIndex >= 0 && addIndex > clientIndex) {
3423                     addIndex = clientIndex;
3424                 }
3425             }
3426             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3427         }
3428
3429         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3430                 + mLruProcessActivityStart + "): " + app);
3431         */
3432
3433         if (lrui >= 0) {
3434             if (lrui < mLruProcessActivityStart) {
3435                 mLruProcessActivityStart--;
3436             }
3437             if (lrui < mLruProcessServiceStart) {
3438                 mLruProcessServiceStart--;
3439             }
3440             /*
3441             if (addIndex > lrui) {
3442                 addIndex--;
3443             }
3444             if (nextIndex > lrui) {
3445                 nextIndex--;
3446             }
3447             */
3448             mLruProcesses.remove(lrui);
3449         }
3450
3451         /*
3452         mLruProcesses.add(addIndex, app);
3453         if (inActivity) {
3454             mLruProcessActivityStart++;
3455         }
3456         if (inService) {
3457             mLruProcessActivityStart++;
3458         }
3459         */
3460
3461         int nextIndex;
3462         if (hasActivity) {
3463             final int N = mLruProcesses.size();
3464             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3465                 // Process doesn't have activities, but has clients with
3466                 // activities...  move it up, but one below the top (the top
3467                 // should always have a real activity).
3468                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3469                         "Adding to second-top of LRU activity list: " + app);
3470                 mLruProcesses.add(N - 1, app);
3471                 // To keep it from spamming the LRU list (by making a bunch of clients),
3472                 // we will push down any other entries owned by the app.
3473                 final int uid = app.info.uid;
3474                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3475                     ProcessRecord subProc = mLruProcesses.get(i);
3476                     if (subProc.info.uid == uid) {
3477                         // We want to push this one down the list.  If the process after
3478                         // it is for the same uid, however, don't do so, because we don't
3479                         // want them internally to be re-ordered.
3480                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3481                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3482                                     "Pushing uid " + uid + " swapping at " + i + ": "
3483                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3484                             ProcessRecord tmp = mLruProcesses.get(i);
3485                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3486                             mLruProcesses.set(i - 1, tmp);
3487                             i--;
3488                         }
3489                     } else {
3490                         // A gap, we can stop here.
3491                         break;
3492                     }
3493                 }
3494             } else {
3495                 // Process has activities, put it at the very tipsy-top.
3496                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3497                 mLruProcesses.add(app);
3498             }
3499             nextIndex = mLruProcessServiceStart;
3500         } else if (hasService) {
3501             // Process has services, put it at the top of the service list.
3502             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3503             mLruProcesses.add(mLruProcessActivityStart, app);
3504             nextIndex = mLruProcessServiceStart;
3505             mLruProcessActivityStart++;
3506         } else  {
3507             // Process not otherwise of interest, it goes to the top of the non-service area.
3508             int index = mLruProcessServiceStart;
3509             if (client != null) {
3510                 // If there is a client, don't allow the process to be moved up higher
3511                 // in the list than that client.
3512                 int clientIndex = mLruProcesses.lastIndexOf(client);
3513                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3514                         + " when updating " + app);
3515                 if (clientIndex <= lrui) {
3516                     // Don't allow the client index restriction to push it down farther in the
3517                     // list than it already is.
3518                     clientIndex = lrui;
3519                 }
3520                 if (clientIndex >= 0 && index > clientIndex) {
3521                     index = clientIndex;
3522                 }
3523             }
3524             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3525             mLruProcesses.add(index, app);
3526             nextIndex = index-1;
3527             mLruProcessActivityStart++;
3528             mLruProcessServiceStart++;
3529         }
3530
3531         // If the app is currently using a content provider or service,
3532         // bump those processes as well.
3533         for (int j=app.connections.size()-1; j>=0; j--) {
3534             ConnectionRecord cr = app.connections.valueAt(j);
3535             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3536                     && cr.binding.service.app != null
3537                     && cr.binding.service.app.lruSeq != mLruSeq
3538                     && !cr.binding.service.app.persistent) {
3539                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3540                         "service connection", cr, app);
3541             }
3542         }
3543         for (int j=app.conProviders.size()-1; j>=0; j--) {
3544             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3545             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3546                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3547                         "provider reference", cpr, app);
3548             }
3549         }
3550     }
3551
3552     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3553         if (uid == SYSTEM_UID) {
3554             // The system gets to run in any process.  If there are multiple
3555             // processes with the same uid, just pick the first (this
3556             // should never happen).
3557             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3558             if (procs == null) return null;
3559             final int procCount = procs.size();
3560             for (int i = 0; i < procCount; i++) {
3561                 final int procUid = procs.keyAt(i);
3562                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3563                     // Don't use an app process or different user process for system component.
3564                     continue;
3565                 }
3566                 return procs.valueAt(i);
3567             }
3568         }
3569         ProcessRecord proc = mProcessNames.get(processName, uid);
3570         if (false && proc != null && !keepIfLarge
3571                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3572                 && proc.lastCachedPss >= 4000) {
3573             // Turn this condition on to cause killing to happen regularly, for testing.
3574             if (proc.baseProcessTracker != null) {
3575                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3576             }
3577             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3578         } else if (proc != null && !keepIfLarge
3579                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3580                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3581             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3582             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3583                 if (proc.baseProcessTracker != null) {
3584                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3585                 }
3586                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3587             }
3588         }
3589         return proc;
3590     }
3591
3592     void notifyPackageUse(String packageName, int reason) {
3593         synchronized(this) {
3594             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3595         }
3596     }
3597
3598     boolean isNextTransitionForward() {
3599         int transit = mWindowManager.getPendingAppTransition();
3600         return transit == TRANSIT_ACTIVITY_OPEN
3601                 || transit == TRANSIT_TASK_OPEN
3602                 || transit == TRANSIT_TASK_TO_FRONT;
3603     }
3604
3605     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3606             String processName, String abiOverride, int uid, Runnable crashHandler) {
3607         synchronized(this) {
3608             ApplicationInfo info = new ApplicationInfo();
3609             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3610             // For isolated processes, the former contains the parent's uid and the latter the
3611             // actual uid of the isolated process.
3612             // In the special case introduced by this method (which is, starting an isolated
3613             // process directly from the SystemServer without an actual parent app process) the
3614             // closest thing to a parent's uid is SYSTEM_UID.
3615             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3616             // the |isolated| logic in the ProcessRecord constructor.
3617             info.uid = SYSTEM_UID;
3618             info.processName = processName;
3619             info.className = entryPoint;
3620             info.packageName = "android";
3621             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3622             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3623                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3624                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3625                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3626                     crashHandler);
3627             return proc != null ? proc.pid : 0;
3628         }
3629     }
3630
3631     final ProcessRecord startProcessLocked(String processName,
3632             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3633             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3634             boolean isolated, boolean keepIfLarge) {
3635         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3636                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3637                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3638                 null /* crashHandler */);
3639     }
3640
3641     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3642             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3643             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3644             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3645         long startTime = SystemClock.elapsedRealtime();
3646         ProcessRecord app;
3647         if (!isolated) {
3648             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3649             checkTime(startTime, "startProcess: after getProcessRecord");
3650
3651             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3652                 // If we are in the background, then check to see if this process
3653                 // is bad.  If so, we will just silently fail.
3654                 if (mAppErrors.isBadProcessLocked(info)) {
3655                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3656                             + "/" + info.processName);
3657                     return null;
3658                 }
3659             } else {
3660                 // When the user is explicitly starting a process, then clear its
3661                 // crash count so that we won't make it bad until they see at
3662                 // least one crash dialog again, and make the process good again
3663                 // if it had been bad.
3664                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3665                         + "/" + info.processName);
3666                 mAppErrors.resetProcessCrashTimeLocked(info);
3667                 if (mAppErrors.isBadProcessLocked(info)) {
3668                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3669                             UserHandle.getUserId(info.uid), info.uid,
3670                             info.processName);
3671                     mAppErrors.clearBadProcessLocked(info);
3672                     if (app != null) {
3673                         app.bad = false;
3674                     }
3675                 }
3676             }
3677         } else {
3678             // If this is an isolated process, it can't re-use an existing process.
3679             app = null;
3680         }
3681
3682         // We don't have to do anything more if:
3683         // (1) There is an existing application record; and
3684         // (2) The caller doesn't think it is dead, OR there is no thread
3685         //     object attached to it so we know it couldn't have crashed; and
3686         // (3) There is a pid assigned to it, so it is either starting or
3687         //     already running.
3688         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3689                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3690                 + " thread=" + (app != null ? app.thread : null)
3691                 + " pid=" + (app != null ? app.pid : -1));
3692         if (app != null && app.pid > 0) {
3693             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3694                 // We already have the app running, or are waiting for it to
3695                 // come up (we have a pid but not yet its thread), so keep it.
3696                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3697                 // If this is a new package in the process, add the package to the list
3698                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3699                 checkTime(startTime, "startProcess: done, added package to proc");
3700                 return app;
3701             }
3702
3703             // An application record is attached to a previous process,
3704             // clean it up now.
3705             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3706             checkTime(startTime, "startProcess: bad proc running, killing");
3707             killProcessGroup(app.uid, app.pid);
3708             handleAppDiedLocked(app, true, true);
3709             checkTime(startTime, "startProcess: done killing old proc");
3710         }
3711
3712         String hostingNameStr = hostingName != null
3713                 ? hostingName.flattenToShortString() : null;
3714
3715         if (app == null) {
3716             checkTime(startTime, "startProcess: creating new process record");
3717             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3718             if (app == null) {
3719                 Slog.w(TAG, "Failed making new process record for "
3720                         + processName + "/" + info.uid + " isolated=" + isolated);
3721                 return null;
3722             }
3723             app.crashHandler = crashHandler;
3724             checkTime(startTime, "startProcess: done creating new process record");
3725         } else {
3726             // If this is a new package in the process, add the package to the list
3727             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3728             checkTime(startTime, "startProcess: added package to existing proc");
3729         }
3730
3731         // If the system is not ready yet, then hold off on starting this
3732         // process until it is.
3733         if (!mProcessesReady
3734                 && !isAllowedWhileBooting(info)
3735                 && !allowWhileBooting) {
3736             if (!mProcessesOnHold.contains(app)) {
3737                 mProcessesOnHold.add(app);
3738             }
3739             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3740                     "System not ready, putting on hold: " + app);
3741             checkTime(startTime, "startProcess: returning with proc on hold");
3742             return app;
3743         }
3744
3745         checkTime(startTime, "startProcess: stepping in to startProcess");
3746         startProcessLocked(
3747                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3748         checkTime(startTime, "startProcess: done starting proc!");
3749         return (app.pid != 0) ? app : null;
3750     }
3751
3752     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3753         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3754     }
3755
3756     private final void startProcessLocked(ProcessRecord app,
3757             String hostingType, String hostingNameStr) {
3758         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3759                 null /* entryPoint */, null /* entryPointArgs */);
3760     }
3761
3762     private final void startProcessLocked(ProcessRecord app, String hostingType,
3763             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3764         long startTime = SystemClock.elapsedRealtime();
3765         if (app.pid > 0 && app.pid != MY_PID) {
3766             checkTime(startTime, "startProcess: removing from pids map");
3767             synchronized (mPidsSelfLocked) {
3768                 mPidsSelfLocked.remove(app.pid);
3769                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3770             }
3771             checkTime(startTime, "startProcess: done removing from pids map");
3772             app.setPid(0);
3773         }
3774
3775         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3776                 "startProcessLocked removing on hold: " + app);
3777         mProcessesOnHold.remove(app);
3778
3779         checkTime(startTime, "startProcess: starting to update cpu stats");
3780         updateCpuStats();
3781         checkTime(startTime, "startProcess: done updating cpu stats");
3782
3783         try {
3784             try {
3785                 final int userId = UserHandle.getUserId(app.uid);
3786                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3787             } catch (RemoteException e) {
3788                 throw e.rethrowAsRuntimeException();
3789             }
3790
3791             int uid = app.uid;
3792             int[] gids = null;
3793             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3794             if (!app.isolated) {
3795                 int[] permGids = null;
3796                 try {
3797                     checkTime(startTime, "startProcess: getting gids from package manager");
3798                     final IPackageManager pm = AppGlobals.getPackageManager();
3799                     permGids = pm.getPackageGids(app.info.packageName,
3800                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3801                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3802                             StorageManagerInternal.class);
3803                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3804                             app.info.packageName);
3805                 } catch (RemoteException e) {
3806                     throw e.rethrowAsRuntimeException();
3807                 }
3808
3809                 /*
3810                  * Add shared application and profile GIDs so applications can share some
3811                  * resources like shared libraries and access user-wide resources
3812                  */
3813                 if (ArrayUtils.isEmpty(permGids)) {
3814                     gids = new int[3];
3815                 } else {
3816                     gids = new int[permGids.length + 3];
3817                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3818                 }
3819                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3820                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3821                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3822
3823                 // Replace any invalid GIDs
3824                 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3825                 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3826             }
3827             checkTime(startTime, "startProcess: building args");
3828             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3829                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3830                         && mTopComponent != null
3831                         && app.processName.equals(mTopComponent.getPackageName())) {
3832                     uid = 0;
3833                 }
3834                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3835                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3836                     uid = 0;
3837                 }
3838             }
3839             int runtimeFlags = 0;
3840             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3841                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3842                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3843                 // Also turn on CheckJNI for debuggable apps. It's quite
3844                 // awkward to turn on otherwise.
3845                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3846             }
3847             // Run the app in safe mode if its manifest requests so or the
3848             // system is booted in safe mode.
3849             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3850                 mSafeMode == true) {
3851                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3852             }
3853             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3854                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3855             }
3856             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3857             if ("true".equals(genDebugInfoProperty)) {
3858                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3859             }
3860             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3861                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3862             }
3863             if ("1".equals(SystemProperties.get("debug.assert"))) {
3864                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3865             }
3866             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3867                 // Enable all debug flags required by the native debugger.
3868                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3869                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3870                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3871                 mNativeDebuggingApp = null;
3872             }
3873
3874             if (app.info.isPrivilegedApp() &&
3875                     !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3876                 runtimeFlags |= Zygote.DISABLE_VERIFIER;
3877                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3878             }
3879
3880             if (app.info.isAllowedToUseHiddenApi()) {
3881                 // This app is allowed to use undocumented and private APIs. Set
3882                 // up its runtime with the appropriate flag.
3883                 runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
3884             }
3885
3886             String invokeWith = null;
3887             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3888                 // Debuggable apps may include a wrapper script with their library directory.
3889                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3890                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3891                 try {
3892                     if (new File(wrapperFileName).exists()) {
3893                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3894                     }
3895                 } finally {
3896                     StrictMode.setThreadPolicy(oldPolicy);
3897                 }
3898             }
3899
3900             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3901             if (requiredAbi == null) {
3902                 requiredAbi = Build.SUPPORTED_ABIS[0];
3903             }
3904
3905             String instructionSet = null;
3906             if (app.info.primaryCpuAbi != null) {
3907                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3908             }
3909
3910             app.gids = gids;
3911             app.requiredAbi = requiredAbi;
3912             app.instructionSet = instructionSet;
3913
3914             // the per-user SELinux context must be set
3915             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3916                 Slog.wtf(TAG, "SELinux tag not defined",
3917                         new IllegalStateException("SELinux tag not defined for "
3918                         + app.info.packageName + " (uid " + app.uid + ")"));
3919             }
3920             final String seInfo = app.info.seInfo
3921                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3922             // Start the process.  It will either succeed and return a result containing
3923             // the PID of the new process, or else throw a RuntimeException.
3924             boolean isActivityProcess = (entryPoint == null);
3925             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3926             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3927                     app.processName);
3928             checkTime(startTime, "startProcess: asking zygote to start proc");
3929             ProcessStartResult startResult;
3930             if (hostingType.equals("webview_service")) {
3931                 startResult = startWebView(entryPoint,
3932                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3933                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3934                         app.info.dataDir, null, entryPointArgs);
3935             } else {
3936                 startResult = Process.start(entryPoint,
3937                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3938                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3939                         app.info.dataDir, invokeWith, entryPointArgs);
3940             }
3941             checkTime(startTime, "startProcess: returned from zygote!");
3942             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3943
3944             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3945             checkTime(startTime, "startProcess: done updating battery stats");
3946
3947             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3948                     UserHandle.getUserId(uid), startResult.pid, uid,
3949                     app.processName, hostingType,
3950                     hostingNameStr != null ? hostingNameStr : "");
3951
3952             try {
3953                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3954                         seInfo, app.info.sourceDir, startResult.pid);
3955             } catch (RemoteException ex) {
3956                 // Ignore
3957             }
3958
3959             if (app.persistent) {
3960                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3961             }
3962
3963             checkTime(startTime, "startProcess: building log message");
3964             StringBuilder buf = mStringBuilder;
3965             buf.setLength(0);
3966             buf.append("Start proc ");
3967             buf.append(startResult.pid);
3968             buf.append(':');
3969             buf.append(app.processName);
3970             buf.append('/');
3971             UserHandle.formatUid(buf, uid);
3972             if (!isActivityProcess) {
3973                 buf.append(" [");
3974                 buf.append(entryPoint);
3975                 buf.append("]");
3976             }
3977             buf.append(" for ");
3978             buf.append(hostingType);
3979             if (hostingNameStr != null) {
3980                 buf.append(" ");
3981                 buf.append(hostingNameStr);
3982             }
3983             Slog.i(TAG, buf.toString());
3984             app.setPid(startResult.pid);
3985             app.usingWrapper = startResult.usingWrapper;
3986             app.removed = false;
3987             app.killed = false;
3988             app.killedByAm = false;
3989             checkTime(startTime, "startProcess: starting to update pids map");
3990             ProcessRecord oldApp;
3991             synchronized (mPidsSelfLocked) {
3992                 oldApp = mPidsSelfLocked.get(startResult.pid);
3993             }
3994             // If there is already an app occupying that pid that hasn't been cleaned up
3995             if (oldApp != null && !app.isolated) {
3996                 // Clean up anything relating to this pid first
3997                 Slog.w(TAG, "Reusing pid " + startResult.pid
3998                         + " while app is still mapped to it");
3999                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4000                         true /*replacingPid*/);
4001             }
4002             synchronized (mPidsSelfLocked) {
4003                 this.mPidsSelfLocked.put(startResult.pid, app);
4004                 if (isActivityProcess) {
4005                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4006                     msg.obj = app;
4007                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4008                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4009                 }
4010             }
4011             checkTime(startTime, "startProcess: done updating pids map");
4012         } catch (RuntimeException e) {
4013             Slog.e(TAG, "Failure starting process " + app.processName, e);
4014
4015             // Something went very wrong while trying to start this process; one
4016             // common case is when the package is frozen due to an active
4017             // upgrade. To recover, clean up any active bookkeeping related to
4018             // starting this process. (We already invoked this method once when
4019             // the package was initially frozen through KILL_APPLICATION_MSG, so
4020             // it doesn't hurt to use it again.)
4021             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4022                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4023         }
4024     }
4025
4026     void updateUsageStats(ActivityRecord component, boolean resumed) {
4027         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4028                 "updateUsageStats: comp=" + component + "res=" + resumed);
4029         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4030         if (resumed) {
4031             if (mUsageStatsService != null) {
4032                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4033                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4034             }
4035             synchronized (stats) {
4036                 stats.noteActivityResumedLocked(component.app.uid);
4037             }
4038         } else {
4039             if (mUsageStatsService != null) {
4040                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4042             }
4043             synchronized (stats) {
4044                 stats.noteActivityPausedLocked(component.app.uid);
4045             }
4046         }
4047     }
4048
4049     Intent getHomeIntent() {
4050         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4051         intent.setComponent(mTopComponent);
4052         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4053         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4054             intent.addCategory(Intent.CATEGORY_HOME);
4055         }
4056         return intent;
4057     }
4058
4059     boolean startHomeActivityLocked(int userId, String reason) {
4060         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4061                 && mTopAction == null) {
4062             // We are running in factory test mode, but unable to find
4063             // the factory test app, so just sit around displaying the
4064             // error message and don't try to start anything.
4065             return false;
4066         }
4067         Intent intent = getHomeIntent();
4068         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4069         if (aInfo != null) {
4070             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4071             // Don't do this if the home app is currently being
4072             // instrumented.
4073             aInfo = new ActivityInfo(aInfo);
4074             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4075             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4076                     aInfo.applicationInfo.uid, true);
4077             if (app == null || app.instr == null) {
4078                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4079                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4080                 // For ANR debugging to verify if the user activity is the one that actually
4081                 // launched.
4082                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4083                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4084             }
4085         } else {
4086             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4087         }
4088
4089         return true;
4090     }
4091
4092     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4093         ActivityInfo ai = null;
4094         ComponentName comp = intent.getComponent();
4095         try {
4096             if (comp != null) {
4097                 // Factory test.
4098                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4099             } else {
4100                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4101                         intent,
4102                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4103                         flags, userId);
4104
4105                 if (info != null) {
4106                     ai = info.activityInfo;
4107                 }
4108             }
4109         } catch (RemoteException e) {
4110             // ignore
4111         }
4112
4113         return ai;
4114     }
4115
4116     /**
4117      * Starts the "new version setup screen" if appropriate.
4118      */
4119     void startSetupActivityLocked() {
4120         // Only do this once per boot.
4121         if (mCheckedForSetup) {
4122             return;
4123         }
4124
4125         // We will show this screen if the current one is a different
4126         // version than the last one shown, and we are not running in
4127         // low-level factory test mode.
4128         final ContentResolver resolver = mContext.getContentResolver();
4129         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4130                 Settings.Global.getInt(resolver,
4131                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4132             mCheckedForSetup = true;
4133
4134             // See if we should be showing the platform update setup UI.
4135             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4136             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4137                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4138             if (!ris.isEmpty()) {
4139                 final ResolveInfo ri = ris.get(0);
4140                 String vers = ri.activityInfo.metaData != null
4141                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4142                         : null;
4143                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4144                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4145                             Intent.METADATA_SETUP_VERSION);
4146                 }
4147                 String lastVers = Settings.Secure.getString(
4148                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4149                 if (vers != null && !vers.equals(lastVers)) {
4150                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4151                     intent.setComponent(new ComponentName(
4152                             ri.activityInfo.packageName, ri.activityInfo.name));
4153                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4154                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4155                             null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4156                 }
4157             }
4158         }
4159     }
4160
4161     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4162         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4163     }
4164
4165     void enforceNotIsolatedCaller(String caller) {
4166         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4167             throw new SecurityException("Isolated process not allowed to call " + caller);
4168         }
4169     }
4170
4171     void enforceShellRestriction(String restriction, int userHandle) {
4172         if (Binder.getCallingUid() == SHELL_UID) {
4173             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4174                 throw new SecurityException("Shell does not have permission to access user "
4175                         + userHandle);
4176             }
4177         }
4178     }
4179
4180     @Override
4181     public int getFrontActivityScreenCompatMode() {
4182         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4183         synchronized (this) {
4184             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4185         }
4186     }
4187
4188     @Override
4189     public void setFrontActivityScreenCompatMode(int mode) {
4190         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4191                 "setFrontActivityScreenCompatMode");
4192         synchronized (this) {
4193             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4194         }
4195     }
4196
4197     @Override
4198     public int getPackageScreenCompatMode(String packageName) {
4199         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4200         synchronized (this) {
4201             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4202         }
4203     }
4204
4205     @Override
4206     public void setPackageScreenCompatMode(String packageName, int mode) {
4207         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4208                 "setPackageScreenCompatMode");
4209         synchronized (this) {
4210             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4211         }
4212     }
4213
4214     @Override
4215     public boolean getPackageAskScreenCompat(String packageName) {
4216         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4217         synchronized (this) {
4218             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4219         }
4220     }
4221
4222     @Override
4223     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4224         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4225                 "setPackageAskScreenCompat");
4226         synchronized (this) {
4227             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4228         }
4229     }
4230
4231     private boolean hasUsageStatsPermission(String callingPackage) {
4232         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4233                 Binder.getCallingUid(), callingPackage);
4234         if (mode == AppOpsManager.MODE_DEFAULT) {
4235             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4236                     == PackageManager.PERMISSION_GRANTED;
4237         }
4238         return mode == AppOpsManager.MODE_ALLOWED;
4239     }
4240
4241     @Override
4242     public int getPackageProcessState(String packageName, String callingPackage) {
4243         if (!hasUsageStatsPermission(callingPackage)) {
4244             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4245                     "getPackageProcessState");
4246         }
4247
4248         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4249         synchronized (this) {
4250             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4251                 final ProcessRecord proc = mLruProcesses.get(i);
4252                 if (procState > proc.setProcState) {
4253                     if (proc.pkgList.containsKey(packageName) ||
4254                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4255                         procState = proc.setProcState;
4256                     }
4257                 }
4258             }
4259         }
4260         return procState;
4261     }
4262
4263     @Override
4264     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4265             throws RemoteException {
4266         synchronized (this) {
4267             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4268             if (app == null) {
4269                 throw new IllegalArgumentException("Unknown process: " + process);
4270             }
4271             if (app.thread == null) {
4272                 throw new IllegalArgumentException("Process has no app thread");
4273             }
4274             if (app.trimMemoryLevel >= level) {
4275                 throw new IllegalArgumentException(
4276                         "Unable to set a higher trim level than current level");
4277             }
4278             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4279                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4280                 throw new IllegalArgumentException("Unable to set a background trim level "
4281                     + "on a foreground process");
4282             }
4283             app.thread.scheduleTrimMemory(level);
4284             app.trimMemoryLevel = level;
4285             return true;
4286         }
4287     }
4288
4289     private void dispatchProcessesChanged() {
4290         int N;
4291         synchronized (this) {
4292             N = mPendingProcessChanges.size();
4293             if (mActiveProcessChanges.length < N) {
4294                 mActiveProcessChanges = new ProcessChangeItem[N];
4295             }
4296             mPendingProcessChanges.toArray(mActiveProcessChanges);
4297             mPendingProcessChanges.clear();
4298             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4299                     "*** Delivering " + N + " process changes");
4300         }
4301
4302         int i = mProcessObservers.beginBroadcast();
4303         while (i > 0) {
4304             i--;
4305             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4306             if (observer != null) {
4307                 try {
4308                     for (int j=0; j<N; j++) {
4309                         ProcessChangeItem item = mActiveProcessChanges[j];
4310                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4311                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4312                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4313                                     + item.uid + ": " + item.foregroundActivities);
4314                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4315                                     item.foregroundActivities);
4316                         }
4317                     }
4318                 } catch (RemoteException e) {
4319                 }
4320             }
4321         }
4322         mProcessObservers.finishBroadcast();
4323
4324         synchronized (this) {
4325             for (int j=0; j<N; j++) {
4326                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4327             }
4328         }
4329     }
4330
4331     private void dispatchProcessDied(int pid, int uid) {
4332         int i = mProcessObservers.beginBroadcast();
4333         while (i > 0) {
4334             i--;
4335             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4336             if (observer != null) {
4337                 try {
4338                     observer.onProcessDied(pid, uid);
4339                 } catch (RemoteException e) {
4340                 }
4341             }
4342         }
4343         mProcessObservers.finishBroadcast();
4344     }
4345
4346     @VisibleForTesting
4347     void dispatchUidsChanged() {
4348         int N;
4349         synchronized (this) {
4350             N = mPendingUidChanges.size();
4351             if (mActiveUidChanges.length < N) {
4352                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4353             }
4354             for (int i=0; i<N; i++) {
4355                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4356                 mActiveUidChanges[i] = change;
4357                 if (change.uidRecord != null) {
4358                     change.uidRecord.pendingChange = null;
4359                     change.uidRecord = null;
4360                 }
4361             }
4362             mPendingUidChanges.clear();
4363             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4364                     "*** Delivering " + N + " uid changes");
4365         }
4366
4367         int i = mUidObservers.beginBroadcast();
4368         while (i > 0) {
4369             i--;
4370             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4371                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4372         }
4373         mUidObservers.finishBroadcast();
4374
4375         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4376             for (int j = 0; j < N; ++j) {
4377                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4378                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4379                     mValidateUids.remove(item.uid);
4380                 } else {
4381                     UidRecord validateUid = mValidateUids.get(item.uid);
4382                     if (validateUid == null) {
4383                         validateUid = new UidRecord(item.uid);
4384                         mValidateUids.put(item.uid, validateUid);
4385                     }
4386                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4387                         validateUid.idle = true;
4388                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4389                         validateUid.idle = false;
4390                     }
4391                     validateUid.curProcState = validateUid.setProcState = item.processState;
4392                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4393                 }
4394             }
4395         }
4396
4397         synchronized (this) {
4398             for (int j = 0; j < N; j++) {
4399                 mAvailUidChanges.add(mActiveUidChanges[j]);
4400             }
4401         }
4402     }
4403
4404     private void dispatchUidsChangedForObserver(IUidObserver observer,
4405             UidObserverRegistration reg, int changesSize) {
4406         if (observer == null) {
4407             return;
4408         }
4409         try {
4410             for (int j = 0; j < changesSize; j++) {
4411                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4412                 final int change = item.change;
4413                 if (change == UidRecord.CHANGE_PROCSTATE &&
4414                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4415                     // No-op common case: no significant change, the observer is not
4416                     // interested in all proc state changes.
4417                     continue;
4418                 }
4419                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4420                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4421                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                 "UID idle uid=" + item.uid);
4423                         observer.onUidIdle(item.uid, item.ephemeral);
4424                     }
4425                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4426                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4427                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4428                                 "UID active uid=" + item.uid);
4429                         observer.onUidActive(item.uid);
4430                     }
4431                 }
4432                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4433                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
4434                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4435                                 "UID cached uid=" + item.uid);
4436                         observer.onUidCachedChanged(item.uid, true);
4437                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4438                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4439                                 "UID active uid=" + item.uid);
4440                         observer.onUidCachedChanged(item.uid, false);
4441                     }
4442                 }
4443                 if ((change & UidRecord.CHANGE_GONE) != 0) {
4444                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4445                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4446                                 "UID gone uid=" + item.uid);
4447                         observer.onUidGone(item.uid, item.ephemeral);
4448                     }
4449                     if (reg.lastProcStates != null) {
4450                         reg.lastProcStates.delete(item.uid);
4451                     }
4452                 } else {
4453                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4454                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4455                                 "UID CHANGED uid=" + item.uid
4456                                         + ": " + item.processState);
4457                         boolean doReport = true;
4458                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4459                             final int lastState = reg.lastProcStates.get(item.uid,
4460                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4461                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4462                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4463                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4464                                 doReport = lastAboveCut != newAboveCut;
4465                             } else {
4466                                 doReport = item.processState
4467                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4468                             }
4469                         }
4470                         if (doReport) {
4471                             if (reg.lastProcStates != null) {
4472                                 reg.lastProcStates.put(item.uid, item.processState);
4473                             }
4474                             observer.onUidStateChanged(item.uid, item.processState,
4475                                     item.procStateSeq);
4476                         }
4477                     }
4478                 }
4479             }
4480         } catch (RemoteException e) {
4481         }
4482     }
4483
4484     void dispatchOomAdjObserver(String msg) {
4485         OomAdjObserver observer;
4486         synchronized (this) {
4487             observer = mCurOomAdjObserver;
4488         }
4489
4490         if (observer != null) {
4491             observer.onOomAdjMessage(msg);
4492         }
4493     }
4494
4495     void setOomAdjObserver(int uid, OomAdjObserver observer) {
4496         synchronized (this) {
4497             mCurOomAdjUid = uid;
4498             mCurOomAdjObserver = observer;
4499         }
4500     }
4501
4502     void clearOomAdjObserver() {
4503         synchronized (this) {
4504             mCurOomAdjUid = -1;
4505             mCurOomAdjObserver = null;
4506         }
4507     }
4508
4509     void reportOomAdjMessageLocked(String tag, String msg) {
4510         Slog.d(tag, msg);
4511         if (mCurOomAdjObserver != null) {
4512             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4513         }
4514     }
4515
4516     @Override
4517     public final int startActivity(IApplicationThread caller, String callingPackage,
4518             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4519             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4520         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4521                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4522                 UserHandle.getCallingUserId());
4523     }
4524
4525     @Override
4526     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4527             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4528             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4529         enforceNotIsolatedCaller("startActivity");
4530         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4531                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4532         // TODO: Switch to user app stacks here.
4533         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4534                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4535                 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4536     }
4537
4538     @Override
4539     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4540             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4541             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4542             int userId) {
4543
4544         // This is very dangerous -- it allows you to perform a start activity (including
4545         // permission grants) as any app that may launch one of your own activities.  So
4546         // we will only allow this to be done from activities that are part of the core framework,
4547         // and then only when they are running as the system.
4548         final ActivityRecord sourceRecord;
4549         final int targetUid;
4550         final String targetPackage;
4551         synchronized (this) {
4552             if (resultTo == null) {
4553                 throw new SecurityException("Must be called from an activity");
4554             }
4555             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4556             if (sourceRecord == null) {
4557                 throw new SecurityException("Called with bad activity token: " + resultTo);
4558             }
4559             if (!sourceRecord.info.packageName.equals("android")) {
4560                 throw new SecurityException(
4561                         "Must be called from an activity that is declared in the android package");
4562             }
4563             if (sourceRecord.app == null) {
4564                 throw new SecurityException("Called without a process attached to activity");
4565             }
4566             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4567                 // This is still okay, as long as this activity is running under the
4568                 // uid of the original calling activity.
4569                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4570                     throw new SecurityException(
4571                             "Calling activity in uid " + sourceRecord.app.uid
4572                                     + " must be system uid or original calling uid "
4573                                     + sourceRecord.launchedFromUid);
4574                 }
4575             }
4576             if (ignoreTargetSecurity) {
4577                 if (intent.getComponent() == null) {
4578                     throw new SecurityException(
4579                             "Component must be specified with ignoreTargetSecurity");
4580                 }
4581                 if (intent.getSelector() != null) {
4582                     throw new SecurityException(
4583                             "Selector not allowed with ignoreTargetSecurity");
4584                 }
4585             }
4586             targetUid = sourceRecord.launchedFromUid;
4587             targetPackage = sourceRecord.launchedFromPackage;
4588         }
4589
4590         if (userId == UserHandle.USER_NULL) {
4591             userId = UserHandle.getUserId(sourceRecord.app.uid);
4592         }
4593
4594         // TODO: Switch to user app stacks here.
4595         try {
4596             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4597                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4598                     null, null, bOptions, ignoreTargetSecurity, userId, null,
4599                     "startActivityAsCaller");
4600             return ret;
4601         } catch (SecurityException e) {
4602             // XXX need to figure out how to propagate to original app.
4603             // A SecurityException here is generally actually a fault of the original
4604             // calling activity (such as a fairly granting permissions), so propagate it
4605             // back to them.
4606             /*
4607             StringBuilder msg = new StringBuilder();
4608             msg.append("While launching");
4609             msg.append(intent.toString());
4610             msg.append(": ");
4611             msg.append(e.getMessage());
4612             */
4613             throw e;
4614         }
4615     }
4616
4617     @Override
4618     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4619             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4620             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4621         enforceNotIsolatedCaller("startActivityAndWait");
4622         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4623                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4624         WaitResult res = new WaitResult();
4625         // TODO: Switch to user app stacks here.
4626         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4627                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4628                 bOptions, false, userId, null, "startActivityAndWait");
4629         return res;
4630     }
4631
4632     @Override
4633     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4634             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4635             int startFlags, Configuration config, Bundle bOptions, int userId) {
4636         enforceNotIsolatedCaller("startActivityWithConfig");
4637         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4638                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4639         // TODO: Switch to user app stacks here.
4640         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4641                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4642                 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4643         return ret;
4644     }
4645
4646     @Override
4647     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4648             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4649             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4650             throws TransactionTooLargeException {
4651         enforceNotIsolatedCaller("startActivityIntentSender");
4652         // Refuse possible leaked file descriptors
4653         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4654             throw new IllegalArgumentException("File descriptors passed in Intent");
4655         }
4656
4657         if (!(target instanceof PendingIntentRecord)) {
4658             throw new IllegalArgumentException("Bad PendingIntent object");
4659         }
4660
4661         PendingIntentRecord pir = (PendingIntentRecord)target;
4662
4663         synchronized (this) {
4664             // If this is coming from the currently resumed activity, it is
4665             // effectively saying that app switches are allowed at this point.
4666             final ActivityStack stack = getFocusedStack();
4667             if (stack.mResumedActivity != null &&
4668                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4669                 mAppSwitchesAllowedTime = 0;
4670             }
4671         }
4672         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4673                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4674         return ret;
4675     }
4676
4677     @Override
4678     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4679             Intent intent, String resolvedType, IVoiceInteractionSession session,
4680             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4681             Bundle bOptions, int userId) {
4682         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4683                 != PackageManager.PERMISSION_GRANTED) {
4684             String msg = "Permission Denial: startVoiceActivity() from pid="
4685                     + Binder.getCallingPid()
4686                     + ", uid=" + Binder.getCallingUid()
4687                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4688             Slog.w(TAG, msg);
4689             throw new SecurityException(msg);
4690         }
4691         if (session == null || interactor == null) {
4692             throw new NullPointerException("null session or interactor");
4693         }
4694         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4695                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4696         // TODO: Switch to user app stacks here.
4697         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4698                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4699                 null, bOptions, false, userId, null, "startVoiceActivity");
4700     }
4701
4702     @Override
4703     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4704             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4705         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4706                 != PackageManager.PERMISSION_GRANTED) {
4707             final String msg = "Permission Denial: startAssistantActivity() from pid="
4708                     + Binder.getCallingPid()
4709                     + ", uid=" + Binder.getCallingUid()
4710                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4711             Slog.w(TAG, msg);
4712             throw new SecurityException(msg);
4713         }
4714         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4715                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4716         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4717                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4718                 userId, null, "startAssistantActivity");
4719     }
4720
4721     @Override
4722     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4723             throws RemoteException {
4724         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4725         synchronized (this) {
4726             ActivityRecord activity = getFocusedStack().topActivity();
4727             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4728                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4729             }
4730             if (mRunningVoice != null || activity.getTask().voiceSession != null
4731                     || activity.voiceSession != null) {
4732                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4733                 return;
4734             }
4735             if (activity.pendingVoiceInteractionStart) {
4736                 Slog.w(TAG, "Pending start of voice interaction already.");
4737                 return;
4738             }
4739             activity.pendingVoiceInteractionStart = true;
4740         }
4741         LocalServices.getService(VoiceInteractionManagerInternal.class)
4742                 .startLocalVoiceInteraction(callingActivity, options);
4743     }
4744
4745     @Override
4746     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4747         LocalServices.getService(VoiceInteractionManagerInternal.class)
4748                 .stopLocalVoiceInteraction(callingActivity);
4749     }
4750
4751     @Override
4752     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4753         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4754                 .supportsLocalVoiceInteraction();
4755     }
4756
4757     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4758             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4759         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4760         if (activityToCallback == null) return;
4761         activityToCallback.setVoiceSessionLocked(voiceSession);
4762
4763         // Inform the activity
4764         try {
4765             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4766                     voiceInteractor);
4767             long token = Binder.clearCallingIdentity();
4768             try {
4769                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4770             } finally {
4771                 Binder.restoreCallingIdentity(token);
4772             }
4773             // TODO: VI Should we cache the activity so that it's easier to find later
4774             // rather than scan through all the stacks and activities?
4775         } catch (RemoteException re) {
4776             activityToCallback.clearVoiceSessionLocked();
4777             // TODO: VI Should this terminate the voice session?
4778         }
4779     }
4780
4781     @Override
4782     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4783         synchronized (this) {
4784             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4785                 if (keepAwake) {
4786                     mVoiceWakeLock.acquire();
4787                 } else {
4788                     mVoiceWakeLock.release();
4789                 }
4790             }
4791         }
4792     }
4793
4794     @Override
4795     public boolean startNextMatchingActivity(IBinder callingActivity,
4796             Intent intent, Bundle bOptions) {
4797         // Refuse possible leaked file descriptors
4798         if (intent != null && intent.hasFileDescriptors() == true) {
4799             throw new IllegalArgumentException("File descriptors passed in Intent");
4800         }
4801         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4802
4803         synchronized (this) {
4804             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4805             if (r == null) {
4806                 ActivityOptions.abort(options);
4807                 return false;
4808             }
4809             if (r.app == null || r.app.thread == null) {
4810                 // The caller is not running...  d'oh!
4811                 ActivityOptions.abort(options);
4812                 return false;
4813             }
4814             intent = new Intent(intent);
4815             // The caller is not allowed to change the data.
4816             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4817             // And we are resetting to find the next component...
4818             intent.setComponent(null);
4819
4820             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4821
4822             ActivityInfo aInfo = null;
4823             try {
4824                 List<ResolveInfo> resolves =
4825                     AppGlobals.getPackageManager().queryIntentActivities(
4826                             intent, r.resolvedType,
4827                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4828                             UserHandle.getCallingUserId()).getList();
4829
4830                 // Look for the original activity in the list...
4831                 final int N = resolves != null ? resolves.size() : 0;
4832                 for (int i=0; i<N; i++) {
4833                     ResolveInfo rInfo = resolves.get(i);
4834                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4835                             && rInfo.activityInfo.name.equals(r.info.name)) {
4836                         // We found the current one...  the next matching is
4837                         // after it.
4838                         i++;
4839                         if (i<N) {
4840                             aInfo = resolves.get(i).activityInfo;
4841                         }
4842                         if (debug) {
4843                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4844                                     + "/" + r.info.name);
4845                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4846                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4847                         }
4848                         break;
4849                     }
4850                 }
4851             } catch (RemoteException e) {
4852             }
4853
4854             if (aInfo == null) {
4855                 // Nobody who is next!
4856                 ActivityOptions.abort(options);
4857                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4858                 return false;
4859             }
4860
4861             intent.setComponent(new ComponentName(
4862                     aInfo.applicationInfo.packageName, aInfo.name));
4863             intent.setFlags(intent.getFlags()&~(
4864                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4865                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4866                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4867                     Intent.FLAG_ACTIVITY_NEW_TASK));
4868
4869             // Okay now we need to start the new activity, replacing the
4870             // currently running activity.  This is a little tricky because
4871             // we want to start the new one as if the current one is finished,
4872             // but not finish the current one first so that there is no flicker.
4873             // And thus...
4874             final boolean wasFinishing = r.finishing;
4875             r.finishing = true;
4876
4877             // Propagate reply information over to the new activity.
4878             final ActivityRecord resultTo = r.resultTo;
4879             final String resultWho = r.resultWho;
4880             final int requestCode = r.requestCode;
4881             r.resultTo = null;
4882             if (resultTo != null) {
4883                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4884             }
4885
4886             final long origId = Binder.clearCallingIdentity();
4887             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4888                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4889                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4890                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4891                     false, false, null, null, "startNextMatchingActivity");
4892             Binder.restoreCallingIdentity(origId);
4893
4894             r.finishing = wasFinishing;
4895             if (res != ActivityManager.START_SUCCESS) {
4896                 return false;
4897             }
4898             return true;
4899         }
4900     }
4901
4902     @Override
4903     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4904         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4905             String msg = "Permission Denial: startActivityFromRecents called without " +
4906                     START_TASKS_FROM_RECENTS;
4907             Slog.w(TAG, msg);
4908             throw new SecurityException(msg);
4909         }
4910         final long origId = Binder.clearCallingIdentity();
4911         try {
4912             synchronized (this) {
4913                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4914             }
4915         } finally {
4916             Binder.restoreCallingIdentity(origId);
4917         }
4918     }
4919
4920     final int startActivityInPackage(int uid, String callingPackage,
4921             Intent intent, String resolvedType, IBinder resultTo,
4922             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4923             TaskRecord inTask, String reason) {
4924
4925         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4926                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4927
4928         // TODO: Switch to user app stacks here.
4929         return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4930                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4931                 null, null, null, bOptions, false, userId, inTask, reason);
4932     }
4933
4934     @Override
4935     public final int startActivities(IApplicationThread caller, String callingPackage,
4936             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4937             int userId) {
4938         final String reason = "startActivities";
4939         enforceNotIsolatedCaller(reason);
4940         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4941                 userId, false, ALLOW_FULL_ONLY, reason, null);
4942         // TODO: Switch to user app stacks here.
4943         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4944                 resolvedTypes, resultTo, bOptions, userId, reason);
4945         return ret;
4946     }
4947
4948     final int startActivitiesInPackage(int uid, String callingPackage,
4949             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4950             Bundle bOptions, int userId) {
4951
4952         final String reason = "startActivityInPackage";
4953         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4954                 userId, false, ALLOW_FULL_ONLY, reason, null);
4955         // TODO: Switch to user app stacks here.
4956         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4957                 resultTo, bOptions, userId, reason);
4958         return ret;
4959     }
4960
4961     @Override
4962     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4963         synchronized (this) {
4964             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4965             if (r == null) {
4966                 return;
4967             }
4968             r.reportFullyDrawnLocked(restoredFromBundle);
4969         }
4970     }
4971
4972     @Override
4973     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4974         synchronized (this) {
4975             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4976             if (r == null) {
4977                 return;
4978             }
4979             final long origId = Binder.clearCallingIdentity();
4980             try {
4981                 r.setRequestedOrientation(requestedOrientation);
4982             } finally {
4983                 Binder.restoreCallingIdentity(origId);
4984             }
4985         }
4986     }
4987
4988     @Override
4989     public int getRequestedOrientation(IBinder token) {
4990         synchronized (this) {
4991             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4992             if (r == null) {
4993                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4994             }
4995             return r.getRequestedOrientation();
4996         }
4997     }
4998
4999     @Override
5000     public final void requestActivityRelaunch(IBinder token) {
5001         synchronized(this) {
5002             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5003             if (r == null) {
5004                 return;
5005             }
5006             final long origId = Binder.clearCallingIdentity();
5007             try {
5008                 r.forceNewConfig = true;
5009                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5010                         true /* preserveWindow */);
5011             } finally {
5012                 Binder.restoreCallingIdentity(origId);
5013             }
5014         }
5015     }
5016
5017     /**
5018      * This is the internal entry point for handling Activity.finish().
5019      *
5020      * @param token The Binder token referencing the Activity we want to finish.
5021      * @param resultCode Result code, if any, from this Activity.
5022      * @param resultData Result data (Intent), if any, from this Activity.
5023      * @param finishTask Whether to finish the task associated with this Activity.
5024      *
5025      * @return Returns true if the activity successfully finished, or false if it is still running.
5026      */
5027     @Override
5028     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5029             int finishTask) {
5030         // Refuse possible leaked file descriptors
5031         if (resultData != null && resultData.hasFileDescriptors() == true) {
5032             throw new IllegalArgumentException("File descriptors passed in Intent");
5033         }
5034
5035         synchronized(this) {
5036             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5037             if (r == null) {
5038                 return true;
5039             }
5040             // Keep track of the root activity of the task before we finish it
5041             TaskRecord tr = r.getTask();
5042             ActivityRecord rootR = tr.getRootActivity();
5043             if (rootR == null) {
5044                 Slog.w(TAG, "Finishing task with all activities already finished");
5045             }
5046             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5047             // finish.
5048             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5049                     mStackSupervisor.isLastLockedTask(tr)) {
5050                 Slog.i(TAG, "Not finishing task in lock task mode");
5051                 mStackSupervisor.showLockTaskToast();
5052                 return false;
5053             }
5054             if (mController != null) {
5055                 // Find the first activity that is not finishing.
5056                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5057                 if (next != null) {
5058                     // ask watcher if this is allowed
5059                     boolean resumeOK = true;
5060                     try {
5061                         resumeOK = mController.activityResuming(next.packageName);
5062                     } catch (RemoteException e) {
5063                         mController = null;
5064                         Watchdog.getInstance().setActivityController(null);
5065                     }
5066
5067                     if (!resumeOK) {
5068                         Slog.i(TAG, "Not finishing activity because controller resumed");
5069                         return false;
5070                     }
5071                 }
5072             }
5073             final long origId = Binder.clearCallingIdentity();
5074             try {
5075                 boolean res;
5076                 final boolean finishWithRootActivity =
5077                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5078                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5079                         || (finishWithRootActivity && r == rootR)) {
5080                     // If requested, remove the task that is associated to this activity only if it
5081                     // was the root activity in the task. The result code and data is ignored
5082                     // because we don't support returning them across task boundaries. Also, to
5083                     // keep backwards compatibility we remove the task from recents when finishing
5084                     // task with root activity.
5085                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5086                     if (!res) {
5087                         Slog.i(TAG, "Removing task failed to finish activity");
5088                     }
5089                 } else {
5090                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5091                             resultData, "app-request", true);
5092                     if (!res) {
5093                         Slog.i(TAG, "Failed to finish by app-request");
5094                     }
5095                 }
5096                 return res;
5097             } finally {
5098                 Binder.restoreCallingIdentity(origId);
5099             }
5100         }
5101     }
5102
5103     @Override
5104     public final void finishHeavyWeightApp() {
5105         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5106                 != PackageManager.PERMISSION_GRANTED) {
5107             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5108                     + Binder.getCallingPid()
5109                     + ", uid=" + Binder.getCallingUid()
5110                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5111             Slog.w(TAG, msg);
5112             throw new SecurityException(msg);
5113         }
5114
5115         synchronized(this) {
5116             if (mHeavyWeightProcess == null) {
5117                 return;
5118             }
5119
5120             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5121             for (int i = 0; i < activities.size(); i++) {
5122                 ActivityRecord r = activities.get(i);
5123                 if (!r.finishing && r.isInStackLocked()) {
5124                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5125                             null, "finish-heavy", true);
5126                 }
5127             }
5128
5129             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5130                     mHeavyWeightProcess.userId, 0));
5131             mHeavyWeightProcess = null;
5132         }
5133     }
5134
5135     @Override
5136     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5137             String message) {
5138         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5139                 != PackageManager.PERMISSION_GRANTED) {
5140             String msg = "Permission Denial: crashApplication() from pid="
5141                     + Binder.getCallingPid()
5142                     + ", uid=" + Binder.getCallingUid()
5143                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5144             Slog.w(TAG, msg);
5145             throw new SecurityException(msg);
5146         }
5147
5148         synchronized(this) {
5149             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5150         }
5151     }
5152
5153     @Override
5154     public final void finishSubActivity(IBinder token, String resultWho,
5155             int requestCode) {
5156         synchronized(this) {
5157             final long origId = Binder.clearCallingIdentity();
5158             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5159             if (r != null) {
5160                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5161             }
5162             Binder.restoreCallingIdentity(origId);
5163         }
5164     }
5165
5166     @Override
5167     public boolean finishActivityAffinity(IBinder token) {
5168         synchronized(this) {
5169             final long origId = Binder.clearCallingIdentity();
5170             try {
5171                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5172                 if (r == null) {
5173                     return false;
5174                 }
5175
5176                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5177                 // can finish.
5178                 final TaskRecord task = r.getTask();
5179                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5180                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5181                     mStackSupervisor.showLockTaskToast();
5182                     return false;
5183                 }
5184                 return task.getStack().finishActivityAffinityLocked(r);
5185             } finally {
5186                 Binder.restoreCallingIdentity(origId);
5187             }
5188         }
5189     }
5190
5191     @Override
5192     public void finishVoiceTask(IVoiceInteractionSession session) {
5193         synchronized (this) {
5194             final long origId = Binder.clearCallingIdentity();
5195             try {
5196                 // TODO: VI Consider treating local voice interactions and voice tasks
5197                 // differently here
5198                 mStackSupervisor.finishVoiceTask(session);
5199             } finally {
5200                 Binder.restoreCallingIdentity(origId);
5201             }
5202         }
5203
5204     }
5205
5206     @Override
5207     public boolean releaseActivityInstance(IBinder token) {
5208         synchronized(this) {
5209             final long origId = Binder.clearCallingIdentity();
5210             try {
5211                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5212                 if (r == null) {
5213                     return false;
5214                 }
5215                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5216             } finally {
5217                 Binder.restoreCallingIdentity(origId);
5218             }
5219         }
5220     }
5221
5222     @Override
5223     public void releaseSomeActivities(IApplicationThread appInt) {
5224         synchronized(this) {
5225             final long origId = Binder.clearCallingIdentity();
5226             try {
5227                 ProcessRecord app = getRecordForAppLocked(appInt);
5228                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5229             } finally {
5230                 Binder.restoreCallingIdentity(origId);
5231             }
5232         }
5233     }
5234
5235     @Override
5236     public boolean willActivityBeVisible(IBinder token) {
5237         synchronized(this) {
5238             ActivityStack stack = ActivityRecord.getStackLocked(token);
5239             if (stack != null) {
5240                 return stack.willActivityBeVisibleLocked(token);
5241             }
5242             return false;
5243         }
5244     }
5245
5246     @Override
5247     public void overridePendingTransition(IBinder token, String packageName,
5248             int enterAnim, int exitAnim) {
5249         synchronized(this) {
5250             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5251             if (self == null) {
5252                 return;
5253             }
5254
5255             final long origId = Binder.clearCallingIdentity();
5256
5257             if (self.state == ActivityState.RESUMED
5258                     || self.state == ActivityState.PAUSING) {
5259                 mWindowManager.overridePendingAppTransition(packageName,
5260                         enterAnim, exitAnim, null);
5261             }
5262
5263             Binder.restoreCallingIdentity(origId);
5264         }
5265     }
5266
5267     /**
5268      * Main function for removing an existing process from the activity manager
5269      * as a result of that process going away.  Clears out all connections
5270      * to the process.
5271      */
5272     private final void handleAppDiedLocked(ProcessRecord app,
5273             boolean restarting, boolean allowRestart) {
5274         int pid = app.pid;
5275         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5276                 false /*replacingPid*/);
5277         if (!kept && !restarting) {
5278             removeLruProcessLocked(app);
5279             if (pid > 0) {
5280                 ProcessList.remove(pid);
5281             }
5282         }
5283
5284         if (mProfileProc == app) {
5285             clearProfilerLocked();
5286         }
5287
5288         // Remove this application's activities from active lists.
5289         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5290
5291         app.activities.clear();
5292
5293         if (app.instr != null) {
5294             Slog.w(TAG, "Crash of app " + app.processName
5295                   + " running instrumentation " + app.instr.mClass);
5296             Bundle info = new Bundle();
5297             info.putString("shortMsg", "Process crashed.");
5298             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5299         }
5300
5301         mWindowManager.deferSurfaceLayout();
5302         try {
5303             if (!restarting && hasVisibleActivities
5304                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5305                 // If there was nothing to resume, and we are not already restarting this process, but
5306                 // there is a visible activity that is hosted by the process...  then make sure all
5307                 // visible activities are running, taking care of restarting this process.
5308                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5309             }
5310         } finally {
5311             mWindowManager.continueSurfaceLayout();
5312         }
5313     }
5314
5315     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5316         final IBinder threadBinder = thread.asBinder();
5317         // Find the application record.
5318         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5319             final ProcessRecord rec = mLruProcesses.get(i);
5320             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5321                 return i;
5322             }
5323         }
5324         return -1;
5325     }
5326
5327     final ProcessRecord getRecordForAppLocked(
5328             IApplicationThread thread) {
5329         if (thread == null) {
5330             return null;
5331         }
5332
5333         int appIndex = getLRURecordIndexForAppLocked(thread);
5334         if (appIndex >= 0) {
5335             return mLruProcesses.get(appIndex);
5336         }
5337
5338         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5339         // double-check that.
5340         final IBinder threadBinder = thread.asBinder();
5341         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5342         for (int i = pmap.size()-1; i >= 0; i--) {
5343             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5344             for (int j = procs.size()-1; j >= 0; j--) {
5345                 final ProcessRecord proc = procs.valueAt(j);
5346                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5347                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5348                             + proc);
5349                     return proc;
5350                 }
5351             }
5352         }
5353
5354         return null;
5355     }
5356
5357     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5358         // If there are no longer any background processes running,
5359         // and the app that died was not running instrumentation,
5360         // then tell everyone we are now low on memory.
5361         boolean haveBg = false;
5362         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5363             ProcessRecord rec = mLruProcesses.get(i);
5364             if (rec.thread != null
5365                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5366                 haveBg = true;
5367                 break;
5368             }
5369         }
5370
5371         if (!haveBg) {
5372             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5373             if (doReport) {
5374                 long now = SystemClock.uptimeMillis();
5375                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5376                     doReport = false;
5377                 } else {
5378                     mLastMemUsageReportTime = now;
5379                 }
5380             }
5381             final ArrayList<ProcessMemInfo> memInfos
5382                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5383             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5384             long now = SystemClock.uptimeMillis();
5385             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5386                 ProcessRecord rec = mLruProcesses.get(i);
5387                 if (rec == dyingProc || rec.thread == null) {
5388                     continue;
5389                 }
5390                 if (doReport) {
5391                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5392                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5393                 }
5394                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5395                     // The low memory report is overriding any current
5396                     // state for a GC request.  Make sure to do
5397                     // heavy/important/visible/foreground processes first.
5398                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5399                         rec.lastRequestedGc = 0;
5400                     } else {
5401                         rec.lastRequestedGc = rec.lastLowMemory;
5402                     }
5403                     rec.reportLowMemory = true;
5404                     rec.lastLowMemory = now;
5405                     mProcessesToGc.remove(rec);
5406                     addProcessToGcListLocked(rec);
5407                 }
5408             }
5409             if (doReport) {
5410                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5411                 mHandler.sendMessage(msg);
5412             }
5413             scheduleAppGcsLocked();
5414         }
5415     }
5416
5417     final void appDiedLocked(ProcessRecord app) {
5418        appDiedLocked(app, app.pid, app.thread, false);
5419     }
5420
5421     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5422             boolean fromBinderDied) {
5423         // First check if this ProcessRecord is actually active for the pid.
5424         synchronized (mPidsSelfLocked) {
5425             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5426             if (curProc != app) {
5427                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5428                 return;
5429             }
5430         }
5431
5432         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5433         synchronized (stats) {
5434             stats.noteProcessDiedLocked(app.info.uid, pid);
5435         }
5436
5437         if (!app.killed) {
5438             if (!fromBinderDied) {
5439                 killProcessQuiet(pid);
5440             }
5441             killProcessGroup(app.uid, pid);
5442             app.killed = true;
5443         }
5444
5445         // Clean up already done if the process has been re-started.
5446         if (app.pid == pid && app.thread != null &&
5447                 app.thread.asBinder() == thread.asBinder()) {
5448             boolean doLowMem = app.instr == null;
5449             boolean doOomAdj = doLowMem;
5450             if (!app.killedByAm) {
5451                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5452                         + ProcessList.makeOomAdjString(app.setAdj)
5453                         + ProcessList.makeProcStateString(app.setProcState));
5454                 mAllowLowerMemLevel = true;
5455             } else {
5456                 // Note that we always want to do oom adj to update our state with the
5457                 // new number of procs.
5458                 mAllowLowerMemLevel = false;
5459                 doLowMem = false;
5460             }
5461             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5462                     app.setAdj, app.setProcState);
5463             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5464                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5465             handleAppDiedLocked(app, false, true);
5466
5467             if (doOomAdj) {
5468                 updateOomAdjLocked();
5469             }
5470             if (doLowMem) {
5471                 doLowMemReportIfNeededLocked(app);
5472             }
5473         } else if (app.pid != pid) {
5474             // A new process has already been started.
5475             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5476                     + ") has died and restarted (pid " + app.pid + ").");
5477             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5478         } else if (DEBUG_PROCESSES) {
5479             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5480                     + thread.asBinder());
5481         }
5482     }
5483
5484     /**
5485      * If a stack trace dump file is configured, dump process stack traces.
5486      * @param clearTraces causes the dump file to be erased prior to the new
5487      *    traces being written, if true; when false, the new traces will be
5488      *    appended to any existing file content.
5489      * @param firstPids of dalvik VM processes to dump stack traces for first
5490      * @param lastPids of dalvik VM processes to dump stack traces for last
5491      * @param nativePids optional list of native pids to dump stack crawls
5492      */
5493     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5494             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5495             ArrayList<Integer> nativePids) {
5496         ArrayList<Integer> extraPids = null;
5497
5498         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5499         // of the top users at the time of the request.
5500         if (processCpuTracker != null) {
5501             processCpuTracker.init();
5502             try {
5503                 Thread.sleep(200);
5504             } catch (InterruptedException ignored) {
5505             }
5506
5507             processCpuTracker.update();
5508
5509             // We'll take the stack crawls of just the top apps using CPU.
5510             final int N = processCpuTracker.countWorkingStats();
5511             extraPids = new ArrayList<>();
5512             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5513                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5514                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5515                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5516
5517                     extraPids.add(stats.pid);
5518                 } else if (DEBUG_ANR) {
5519                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5520                             + stats.pid);
5521                 }
5522             }
5523         }
5524
5525         boolean useTombstonedForJavaTraces = false;
5526         File tracesFile;
5527
5528         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5529         if (tracesDirProp.isEmpty()) {
5530             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5531             // dumping scheme. All traces are written to a global trace file (usually
5532             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5533             // the file if requested.
5534             //
5535             // This mode of operation will be removed in the near future.
5536
5537
5538             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5539             if (globalTracesPath.isEmpty()) {
5540                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5541                 return null;
5542             }
5543
5544             tracesFile = new File(globalTracesPath);
5545             try {
5546                 if (clearTraces && tracesFile.exists()) {
5547                     tracesFile.delete();
5548                 }
5549
5550                 tracesFile.createNewFile();
5551                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5552             } catch (IOException e) {
5553                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5554                 return null;
5555             }
5556         } else {
5557             File tracesDir = new File(tracesDirProp);
5558             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5559             // Each set of ANR traces is written to a separate file and dumpstate will process
5560             // all such files and add them to a captured bug report if they're recent enough.
5561             maybePruneOldTraces(tracesDir);
5562
5563             // NOTE: We should consider creating the file in native code atomically once we've
5564             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5565             // can be removed.
5566             tracesFile = createAnrDumpFile(tracesDir);
5567             if (tracesFile == null) {
5568                 return null;
5569             }
5570
5571             useTombstonedForJavaTraces = true;
5572         }
5573
5574         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5575                 useTombstonedForJavaTraces);
5576         return tracesFile;
5577     }
5578
5579     @GuardedBy("ActivityManagerService.class")
5580     private static SimpleDateFormat sAnrFileDateFormat;
5581
5582     private static synchronized File createAnrDumpFile(File tracesDir) {
5583         if (sAnrFileDateFormat == null) {
5584             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5585         }
5586
5587         final String formattedDate = sAnrFileDateFormat.format(new Date());
5588         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5589
5590         try {
5591             if (anrFile.createNewFile()) {
5592                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5593                 return anrFile;
5594             } else {
5595                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5596             }
5597         } catch (IOException ioe) {
5598             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5599         }
5600
5601         return null;
5602     }
5603
5604     /**
5605      * Prune all trace files that are more than a day old.
5606      *
5607      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5608      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5609      * since it's the system_server that creates trace files for most ANRs.
5610      */
5611     private static void maybePruneOldTraces(File tracesDir) {
5612         final long now = System.currentTimeMillis();
5613         final File[] traceFiles = tracesDir.listFiles();
5614
5615         if (traceFiles != null) {
5616             for (File file : traceFiles) {
5617                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5618                     if (!file.delete()) {
5619                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
5620                     }
5621                 }
5622             }
5623         }
5624     }
5625
5626     /**
5627      * Legacy code, do not use. Existing users will be deleted.
5628      *
5629      * @deprecated
5630      */
5631     @Deprecated
5632     public static class DumpStackFileObserver extends FileObserver {
5633         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5634         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5635
5636         private final String mTracesPath;
5637         private boolean mClosed;
5638
5639         public DumpStackFileObserver(String tracesPath) {
5640             super(tracesPath, FileObserver.CLOSE_WRITE);
5641             mTracesPath = tracesPath;
5642         }
5643
5644         @Override
5645         public synchronized void onEvent(int event, String path) {
5646             mClosed = true;
5647             notify();
5648         }
5649
5650         public long dumpWithTimeout(int pid, long timeout) {
5651             sendSignal(pid, SIGNAL_QUIT);
5652             final long start = SystemClock.elapsedRealtime();
5653
5654             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5655             synchronized (this) {
5656                 try {
5657                     wait(waitTime); // Wait for traces file to be closed.
5658                 } catch (InterruptedException e) {
5659                     Slog.wtf(TAG, e);
5660                 }
5661             }
5662
5663             // This avoids a corner case of passing a negative time to the native
5664             // trace in case we've already hit the overall timeout.
5665             final long timeWaited = SystemClock.elapsedRealtime() - start;
5666             if (timeWaited >= timeout) {
5667                 return timeWaited;
5668             }
5669
5670             if (!mClosed) {
5671                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5672                        ". Attempting native stack collection.");
5673
5674                 final long nativeDumpTimeoutMs = Math.min(
5675                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5676
5677                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5678                         (int) (nativeDumpTimeoutMs / 1000));
5679             }
5680
5681             final long end = SystemClock.elapsedRealtime();
5682             mClosed = false;
5683
5684             return (end - start);
5685         }
5686     }
5687
5688     /**
5689      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5690      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5691      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5692      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5693      * capturing traces.
5694      */
5695     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5696         final long timeStart = SystemClock.elapsedRealtime();
5697         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5698             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5699                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5700         }
5701
5702         return SystemClock.elapsedRealtime() - timeStart;
5703     }
5704
5705     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5706             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5707             boolean useTombstonedForJavaTraces) {
5708
5709         // We don't need any sort of inotify based monitoring when we're dumping traces via
5710         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5711         // control of all writes to the file in question.
5712         final DumpStackFileObserver observer;
5713         if (useTombstonedForJavaTraces) {
5714             observer = null;
5715         } else {
5716             // Use a FileObserver to detect when traces finish writing.
5717             // The order of traces is considered important to maintain for legibility.
5718             observer = new DumpStackFileObserver(tracesFile);
5719         }
5720
5721         // We must complete all stack dumps within 20 seconds.
5722         long remainingTime = 20 * 1000;
5723         try {
5724             if (observer != null) {
5725                 observer.startWatching();
5726             }
5727
5728             // First collect all of the stacks of the most important pids.
5729             if (firstPids != null) {
5730                 int num = firstPids.size();
5731                 for (int i = 0; i < num; i++) {
5732                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5733                             + firstPids.get(i));
5734                     final long timeTaken;
5735                     if (useTombstonedForJavaTraces) {
5736                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5737                     } else {
5738                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5739                     }
5740
5741                     remainingTime -= timeTaken;
5742                     if (remainingTime <= 0) {
5743                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5744                             "); deadline exceeded.");
5745                         return;
5746                     }
5747
5748                     if (DEBUG_ANR) {
5749                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5750                     }
5751                 }
5752             }
5753
5754             // Next collect the stacks of the native pids
5755             if (nativePids != null) {
5756                 for (int pid : nativePids) {
5757                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5758                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5759
5760                     final long start = SystemClock.elapsedRealtime();
5761                     Debug.dumpNativeBacktraceToFileTimeout(
5762                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5763                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5764
5765                     remainingTime -= timeTaken;
5766                     if (remainingTime <= 0) {
5767                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5768                             "); deadline exceeded.");
5769                         return;
5770                     }
5771
5772                     if (DEBUG_ANR) {
5773                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5774                     }
5775                 }
5776             }
5777
5778             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5779             if (extraPids != null) {
5780                 for (int pid : extraPids) {
5781                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5782
5783                     final long timeTaken;
5784                     if (useTombstonedForJavaTraces) {
5785                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5786                     } else {
5787                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5788                     }
5789
5790                     remainingTime -= timeTaken;
5791                     if (remainingTime <= 0) {
5792                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5793                                 "); deadline exceeded.");
5794                         return;
5795                     }
5796
5797                     if (DEBUG_ANR) {
5798                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5799                     }
5800                 }
5801             }
5802         } finally {
5803             if (observer != null) {
5804                 observer.stopWatching();
5805             }
5806         }
5807     }
5808
5809     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5810         if (true || Build.IS_USER) {
5811             return;
5812         }
5813         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5814         if (tracesPath == null || tracesPath.length() == 0) {
5815             return;
5816         }
5817
5818         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5819         StrictMode.allowThreadDiskWrites();
5820         try {
5821             final File tracesFile = new File(tracesPath);
5822             final File tracesDir = tracesFile.getParentFile();
5823             final File tracesTmp = new File(tracesDir, "__tmp__");
5824             try {
5825                 if (tracesFile.exists()) {
5826                     tracesTmp.delete();
5827                     tracesFile.renameTo(tracesTmp);
5828                 }
5829                 StringBuilder sb = new StringBuilder();
5830                 Time tobj = new Time();
5831                 tobj.set(System.currentTimeMillis());
5832                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5833                 sb.append(": ");
5834                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5835                 sb.append(" since ");
5836                 sb.append(msg);
5837                 FileOutputStream fos = new FileOutputStream(tracesFile);
5838                 fos.write(sb.toString().getBytes());
5839                 if (app == null) {
5840                     fos.write("\n*** No application process!".getBytes());
5841                 }
5842                 fos.close();
5843                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5844             } catch (IOException e) {
5845                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5846                 return;
5847             }
5848
5849             if (app != null) {
5850                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5851                 firstPids.add(app.pid);
5852                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5853             }
5854
5855             File lastTracesFile = null;
5856             File curTracesFile = null;
5857             for (int i=9; i>=0; i--) {
5858                 String name = String.format(Locale.US, "slow%02d.txt", i);
5859                 curTracesFile = new File(tracesDir, name);
5860                 if (curTracesFile.exists()) {
5861                     if (lastTracesFile != null) {
5862                         curTracesFile.renameTo(lastTracesFile);
5863                     } else {
5864                         curTracesFile.delete();
5865                     }
5866                 }
5867                 lastTracesFile = curTracesFile;
5868             }
5869             tracesFile.renameTo(curTracesFile);
5870             if (tracesTmp.exists()) {
5871                 tracesTmp.renameTo(tracesFile);
5872             }
5873         } finally {
5874             StrictMode.setThreadPolicy(oldPolicy);
5875         }
5876     }
5877
5878     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5879         if (!mLaunchWarningShown) {
5880             mLaunchWarningShown = true;
5881             mUiHandler.post(new Runnable() {
5882                 @Override
5883                 public void run() {
5884                     synchronized (ActivityManagerService.this) {
5885                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5886                         d.show();
5887                         mUiHandler.postDelayed(new Runnable() {
5888                             @Override
5889                             public void run() {
5890                                 synchronized (ActivityManagerService.this) {
5891                                     d.dismiss();
5892                                     mLaunchWarningShown = false;
5893                                 }
5894                             }
5895                         }, 4000);
5896                     }
5897                 }
5898             });
5899         }
5900     }
5901
5902     @Override
5903     public boolean clearApplicationUserData(final String packageName,
5904             final IPackageDataObserver observer, int userId) {
5905         enforceNotIsolatedCaller("clearApplicationUserData");
5906         int uid = Binder.getCallingUid();
5907         int pid = Binder.getCallingPid();
5908         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5909                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5910
5911         final ApplicationInfo appInfo;
5912         final boolean isInstantApp;
5913
5914         long callingId = Binder.clearCallingIdentity();
5915         try {
5916             IPackageManager pm = AppGlobals.getPackageManager();
5917             synchronized(this) {
5918                 // Instant packages are not protected
5919                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5920                         resolvedUserId, packageName)) {
5921                     throw new SecurityException(
5922                             "Cannot clear data for a protected package: " + packageName);
5923                 }
5924
5925                 ApplicationInfo applicationInfo = null;
5926                 try {
5927                     applicationInfo = pm.getApplicationInfo(packageName,
5928                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5929                 } catch (RemoteException e) {
5930                     /* ignore */
5931                 }
5932                 appInfo = applicationInfo;
5933
5934                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5935
5936                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5937                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5938                     throw new SecurityException("PID " + pid + " does not have permission "
5939                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5940                             + " of package " + packageName);
5941                 }
5942
5943                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5944                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
5945                 final boolean isUninstalledAppWithoutInstantMetadata =
5946                         (appInfo == null && !hasInstantMetadata);
5947                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5948                         || hasInstantMetadata;
5949                 final boolean canAccessInstantApps = checkComponentPermission(
5950                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5951                         == PackageManager.PERMISSION_GRANTED;
5952
5953                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5954                         && !canAccessInstantApps)) {
5955                     Slog.w(TAG, "Invalid packageName: " + packageName);
5956                     if (observer != null) {
5957                         try {
5958                             observer.onRemoveCompleted(packageName, false);
5959                         } catch (RemoteException e) {
5960                             Slog.i(TAG, "Observer no longer exists.");
5961                         }
5962                     }
5963                     return false;
5964                 }
5965
5966                 if (appInfo != null) {
5967                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5968                     // Remove all tasks match the cleared application package and user
5969                     for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5970                         final TaskRecord tr = mRecentTasks.get(i);
5971                         final String taskPackageName =
5972                                 tr.getBaseIntent().getComponent().getPackageName();
5973                         if (tr.userId != resolvedUserId) continue;
5974                         if (!taskPackageName.equals(packageName)) continue;
5975                         mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5976                                 REMOVE_FROM_RECENTS);
5977                     }
5978                 }
5979             }
5980
5981             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5982                 @Override
5983                 public void onRemoveCompleted(String packageName, boolean succeeded)
5984                         throws RemoteException {
5985                     if (appInfo != null) {
5986                         synchronized (ActivityManagerService.this) {
5987                             finishForceStopPackageLocked(packageName, appInfo.uid);
5988                         }
5989                     }
5990                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5991                             Uri.fromParts("package", packageName, null));
5992                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5993                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5994                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5995                     if (isInstantApp) {
5996                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5997                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5998                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5999                                 resolvedUserId);
6000                     } else {
6001                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6002                                 null, null, null, null, false, false, resolvedUserId);
6003                     }
6004
6005                     if (observer != null) {
6006                         observer.onRemoveCompleted(packageName, succeeded);
6007                     }
6008                 }
6009             };
6010
6011             try {
6012                 // Clear application user data
6013                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6014
6015                 if (appInfo != null) {
6016                     synchronized (this) {
6017                         // Remove all permissions granted from/to this package
6018                         removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6019                     }
6020
6021                     // Reset notification settings.
6022                     INotificationManager inm = NotificationManager.getService();
6023                     inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6024                 }
6025             } catch (RemoteException e) {
6026             }
6027         } finally {
6028             Binder.restoreCallingIdentity(callingId);
6029         }
6030         return true;
6031     }
6032
6033     @Override
6034     public void killBackgroundProcesses(final String packageName, int userId) {
6035         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6036                 != PackageManager.PERMISSION_GRANTED &&
6037                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6038                         != PackageManager.PERMISSION_GRANTED) {
6039             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6040                     + Binder.getCallingPid()
6041                     + ", uid=" + Binder.getCallingUid()
6042                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6043             Slog.w(TAG, msg);
6044             throw new SecurityException(msg);
6045         }
6046
6047         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6048                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6049         long callingId = Binder.clearCallingIdentity();
6050         try {
6051             IPackageManager pm = AppGlobals.getPackageManager();
6052             synchronized(this) {
6053                 int appId = -1;
6054                 try {
6055                     appId = UserHandle.getAppId(
6056                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6057                 } catch (RemoteException e) {
6058                 }
6059                 if (appId == -1) {
6060                     Slog.w(TAG, "Invalid packageName: " + packageName);
6061                     return;
6062                 }
6063                 killPackageProcessesLocked(packageName, appId, userId,
6064                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6065             }
6066         } finally {
6067             Binder.restoreCallingIdentity(callingId);
6068         }
6069     }
6070
6071     @Override
6072     public void killAllBackgroundProcesses() {
6073         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6074                 != PackageManager.PERMISSION_GRANTED) {
6075             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6076                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6077                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6078             Slog.w(TAG, msg);
6079             throw new SecurityException(msg);
6080         }
6081
6082         final long callingId = Binder.clearCallingIdentity();
6083         try {
6084             synchronized (this) {
6085                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6086                 final int NP = mProcessNames.getMap().size();
6087                 for (int ip = 0; ip < NP; ip++) {
6088                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6089                     final int NA = apps.size();
6090                     for (int ia = 0; ia < NA; ia++) {
6091                         final ProcessRecord app = apps.valueAt(ia);
6092                         if (app.persistent) {
6093                             // We don't kill persistent processes.
6094                             continue;
6095                         }
6096                         if (app.removed) {
6097                             procs.add(app);
6098                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6099                             app.removed = true;
6100                             procs.add(app);
6101                         }
6102                     }
6103                 }
6104
6105                 final int N = procs.size();
6106                 for (int i = 0; i < N; i++) {
6107                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6108                 }
6109
6110                 mAllowLowerMemLevel = true;
6111
6112                 updateOomAdjLocked();
6113                 doLowMemReportIfNeededLocked(null);
6114             }
6115         } finally {
6116             Binder.restoreCallingIdentity(callingId);
6117         }
6118     }
6119
6120     /**
6121      * Kills all background processes, except those matching any of the
6122      * specified properties.
6123      *
6124      * @param minTargetSdk the target SDK version at or above which to preserve
6125      *                     processes, or {@code -1} to ignore the target SDK
6126      * @param maxProcState the process state at or below which to preserve
6127      *                     processes, or {@code -1} to ignore the process state
6128      */
6129     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6130         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6131                 != PackageManager.PERMISSION_GRANTED) {
6132             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6133                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6134                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6135             Slog.w(TAG, msg);
6136             throw new SecurityException(msg);
6137         }
6138
6139         final long callingId = Binder.clearCallingIdentity();
6140         try {
6141             synchronized (this) {
6142                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6143                 final int NP = mProcessNames.getMap().size();
6144                 for (int ip = 0; ip < NP; ip++) {
6145                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6146                     final int NA = apps.size();
6147                     for (int ia = 0; ia < NA; ia++) {
6148                         final ProcessRecord app = apps.valueAt(ia);
6149                         if (app.removed) {
6150                             procs.add(app);
6151                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6152                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6153                             app.removed = true;
6154                             procs.add(app);
6155                         }
6156                     }
6157                 }
6158
6159                 final int N = procs.size();
6160                 for (int i = 0; i < N; i++) {
6161                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6162                 }
6163             }
6164         } finally {
6165             Binder.restoreCallingIdentity(callingId);
6166         }
6167     }
6168
6169     @Override
6170     public void forceStopPackage(final String packageName, int userId) {
6171         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6172                 != PackageManager.PERMISSION_GRANTED) {
6173             String msg = "Permission Denial: forceStopPackage() from pid="
6174                     + Binder.getCallingPid()
6175                     + ", uid=" + Binder.getCallingUid()
6176                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6177             Slog.w(TAG, msg);
6178             throw new SecurityException(msg);
6179         }
6180         final int callingPid = Binder.getCallingPid();
6181         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6182                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6183         long callingId = Binder.clearCallingIdentity();
6184         try {
6185             IPackageManager pm = AppGlobals.getPackageManager();
6186             synchronized(this) {
6187                 int[] users = userId == UserHandle.USER_ALL
6188                         ? mUserController.getUsers() : new int[] { userId };
6189                 for (int user : users) {
6190                     int pkgUid = -1;
6191                     try {
6192                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6193                                 user);
6194                     } catch (RemoteException e) {
6195                     }
6196                     if (pkgUid == -1) {
6197                         Slog.w(TAG, "Invalid packageName: " + packageName);
6198                         continue;
6199                     }
6200                     try {
6201                         pm.setPackageStoppedState(packageName, true, user);
6202                     } catch (RemoteException e) {
6203                     } catch (IllegalArgumentException e) {
6204                         Slog.w(TAG, "Failed trying to unstop package "
6205                                 + packageName + ": " + e);
6206                     }
6207                     if (mUserController.isUserRunningLocked(user, 0)) {
6208                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6209                         finishForceStopPackageLocked(packageName, pkgUid);
6210                     }
6211                 }
6212             }
6213         } finally {
6214             Binder.restoreCallingIdentity(callingId);
6215         }
6216     }
6217
6218     @Override
6219     public void addPackageDependency(String packageName) {
6220         synchronized (this) {
6221             int callingPid = Binder.getCallingPid();
6222             if (callingPid == myPid()) {
6223                 //  Yeah, um, no.
6224                 return;
6225             }
6226             ProcessRecord proc;
6227             synchronized (mPidsSelfLocked) {
6228                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6229             }
6230             if (proc != null) {
6231                 if (proc.pkgDeps == null) {
6232                     proc.pkgDeps = new ArraySet<String>(1);
6233                 }
6234                 proc.pkgDeps.add(packageName);
6235             }
6236         }
6237     }
6238
6239     /*
6240      * The pkg name and app id have to be specified.
6241      */
6242     @Override
6243     public void killApplication(String pkg, int appId, int userId, String reason) {
6244         if (pkg == null) {
6245             return;
6246         }
6247         // Make sure the uid is valid.
6248         if (appId < 0) {
6249             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6250             return;
6251         }
6252         int callerUid = Binder.getCallingUid();
6253         // Only the system server can kill an application
6254         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6255             // Post an aysnc message to kill the application
6256             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6257             msg.arg1 = appId;
6258             msg.arg2 = userId;
6259             Bundle bundle = new Bundle();
6260             bundle.putString("pkg", pkg);
6261             bundle.putString("reason", reason);
6262             msg.obj = bundle;
6263             mHandler.sendMessage(msg);
6264         } else {
6265             throw new SecurityException(callerUid + " cannot kill pkg: " +
6266                     pkg);
6267         }
6268     }
6269
6270     @Override
6271     public void closeSystemDialogs(String reason) {
6272         enforceNotIsolatedCaller("closeSystemDialogs");
6273
6274         final int pid = Binder.getCallingPid();
6275         final int uid = Binder.getCallingUid();
6276         final long origId = Binder.clearCallingIdentity();
6277         try {
6278             synchronized (this) {
6279                 // Only allow this from foreground processes, so that background
6280                 // applications can't abuse it to prevent system UI from being shown.
6281                 if (uid >= FIRST_APPLICATION_UID) {
6282                     ProcessRecord proc;
6283                     synchronized (mPidsSelfLocked) {
6284                         proc = mPidsSelfLocked.get(pid);
6285                     }
6286                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6287                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6288                                 + " from background process " + proc);
6289                         return;
6290                     }
6291                 }
6292                 closeSystemDialogsLocked(reason);
6293             }
6294         } finally {
6295             Binder.restoreCallingIdentity(origId);
6296         }
6297     }
6298
6299     void closeSystemDialogsLocked(String reason) {
6300         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6301         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6302                 | Intent.FLAG_RECEIVER_FOREGROUND);
6303         if (reason != null) {
6304             intent.putExtra("reason", reason);
6305         }
6306         mWindowManager.closeSystemDialogs(reason);
6307
6308         mStackSupervisor.closeSystemDialogsLocked();
6309
6310         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6311                 AppOpsManager.OP_NONE, null, false, false,
6312                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6313     }
6314
6315     @Override
6316     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6317         enforceNotIsolatedCaller("getProcessMemoryInfo");
6318         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6319         for (int i=pids.length-1; i>=0; i--) {
6320             ProcessRecord proc;
6321             int oomAdj;
6322             synchronized (this) {
6323                 synchronized (mPidsSelfLocked) {
6324                     proc = mPidsSelfLocked.get(pids[i]);
6325                     oomAdj = proc != null ? proc.setAdj : 0;
6326                 }
6327             }
6328             infos[i] = new Debug.MemoryInfo();
6329             Debug.getMemoryInfo(pids[i], infos[i]);
6330             if (proc != null) {
6331                 synchronized (this) {
6332                     if (proc.thread != null && proc.setAdj == oomAdj) {
6333                         // Record this for posterity if the process has been stable.
6334                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6335                                 infos[i].getTotalUss(), false, proc.pkgList);
6336                     }
6337                 }
6338             }
6339         }
6340         return infos;
6341     }
6342
6343     @Override
6344     public long[] getProcessPss(int[] pids) {
6345         enforceNotIsolatedCaller("getProcessPss");
6346         long[] pss = new long[pids.length];
6347         for (int i=pids.length-1; i>=0; i--) {
6348             ProcessRecord proc;
6349             int oomAdj;
6350             synchronized (this) {
6351                 synchronized (mPidsSelfLocked) {
6352                     proc = mPidsSelfLocked.get(pids[i]);
6353                     oomAdj = proc != null ? proc.setAdj : 0;
6354                 }
6355             }
6356             long[] tmpUss = new long[1];
6357             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6358             if (proc != null) {
6359                 synchronized (this) {
6360                     if (proc.thread != null && proc.setAdj == oomAdj) {
6361                         // Record this for posterity if the process has been stable.
6362                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6363                     }
6364                 }
6365             }
6366         }
6367         return pss;
6368     }
6369
6370     @Override
6371     public void killApplicationProcess(String processName, int uid) {
6372         if (processName == null) {
6373             return;
6374         }
6375
6376         int callerUid = Binder.getCallingUid();
6377         // Only the system server can kill an application
6378         if (callerUid == SYSTEM_UID) {
6379             synchronized (this) {
6380                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6381                 if (app != null && app.thread != null) {
6382                     try {
6383                         app.thread.scheduleSuicide();
6384                     } catch (RemoteException e) {
6385                         // If the other end already died, then our work here is done.
6386                     }
6387                 } else {
6388                     Slog.w(TAG, "Process/uid not found attempting kill of "
6389                             + processName + " / " + uid);
6390                 }
6391             }
6392         } else {
6393             throw new SecurityException(callerUid + " cannot kill app process: " +
6394                     processName);
6395         }
6396     }
6397
6398     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6399         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6400                 false, true, false, false, UserHandle.getUserId(uid), reason);
6401     }
6402
6403     private void finishForceStopPackageLocked(final String packageName, int uid) {
6404         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6405                 Uri.fromParts("package", packageName, null));
6406         if (!mProcessesReady) {
6407             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6408                     | Intent.FLAG_RECEIVER_FOREGROUND);
6409         }
6410         intent.putExtra(Intent.EXTRA_UID, uid);
6411         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6412         broadcastIntentLocked(null, null, intent,
6413                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6414                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6415     }
6416
6417
6418     private final boolean killPackageProcessesLocked(String packageName, int appId,
6419             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6420             boolean doit, boolean evenPersistent, String reason) {
6421         ArrayList<ProcessRecord> procs = new ArrayList<>();
6422
6423         // Remove all processes this package may have touched: all with the
6424         // same UID (except for the system or root user), and all whose name
6425         // matches the package name.
6426         final int NP = mProcessNames.getMap().size();
6427         for (int ip=0; ip<NP; ip++) {
6428             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6429             final int NA = apps.size();
6430             for (int ia=0; ia<NA; ia++) {
6431                 ProcessRecord app = apps.valueAt(ia);
6432                 if (app.persistent && !evenPersistent) {
6433                     // we don't kill persistent processes
6434                     continue;
6435                 }
6436                 if (app.removed) {
6437                     if (doit) {
6438                         procs.add(app);
6439                     }
6440                     continue;
6441                 }
6442
6443                 // Skip process if it doesn't meet our oom adj requirement.
6444                 if (app.setAdj < minOomAdj) {
6445                     continue;
6446                 }
6447
6448                 // If no package is specified, we call all processes under the
6449                 // give user id.
6450                 if (packageName == null) {
6451                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6452                         continue;
6453                     }
6454                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6455                         continue;
6456                     }
6457                 // Package has been specified, we want to hit all processes
6458                 // that match it.  We need to qualify this by the processes
6459                 // that are running under the specified app and user ID.
6460                 } else {
6461                     final boolean isDep = app.pkgDeps != null
6462                             && app.pkgDeps.contains(packageName);
6463                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6464                         continue;
6465                     }
6466                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6467                         continue;
6468                     }
6469                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6470                         continue;
6471                     }
6472                 }
6473
6474                 // Process has passed all conditions, kill it!
6475                 if (!doit) {
6476                     return true;
6477                 }
6478                 app.removed = true;
6479                 procs.add(app);
6480             }
6481         }
6482
6483         int N = procs.size();
6484         for (int i=0; i<N; i++) {
6485             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6486         }
6487         updateOomAdjLocked();
6488         return N > 0;
6489     }
6490
6491     private void cleanupDisabledPackageComponentsLocked(
6492             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6493
6494         Set<String> disabledClasses = null;
6495         boolean packageDisabled = false;
6496         IPackageManager pm = AppGlobals.getPackageManager();
6497
6498         if (changedClasses == null) {
6499             // Nothing changed...
6500             return;
6501         }
6502
6503         // Determine enable/disable state of the package and its components.
6504         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6505         for (int i = changedClasses.length - 1; i >= 0; i--) {
6506             final String changedClass = changedClasses[i];
6507
6508             if (changedClass.equals(packageName)) {
6509                 try {
6510                     // Entire package setting changed
6511                     enabled = pm.getApplicationEnabledSetting(packageName,
6512                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6513                 } catch (Exception e) {
6514                     // No such package/component; probably racing with uninstall.  In any
6515                     // event it means we have nothing further to do here.
6516                     return;
6517                 }
6518                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6519                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6520                 if (packageDisabled) {
6521                     // Entire package is disabled.
6522                     // No need to continue to check component states.
6523                     disabledClasses = null;
6524                     break;
6525                 }
6526             } else {
6527                 try {
6528                     enabled = pm.getComponentEnabledSetting(
6529                             new ComponentName(packageName, changedClass),
6530                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6531                 } catch (Exception e) {
6532                     // As above, probably racing with uninstall.
6533                     return;
6534                 }
6535                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6536                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6537                     if (disabledClasses == null) {
6538                         disabledClasses = new ArraySet<>(changedClasses.length);
6539                     }
6540                     disabledClasses.add(changedClass);
6541                 }
6542             }
6543         }
6544
6545         if (!packageDisabled && disabledClasses == null) {
6546             // Nothing to do here...
6547             return;
6548         }
6549
6550         // Clean-up disabled activities.
6551         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6552                 packageName, disabledClasses, true, false, userId) && mBooted) {
6553             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6554             mStackSupervisor.scheduleIdleLocked();
6555         }
6556
6557         // Clean-up disabled tasks
6558         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6559
6560         // Clean-up disabled services.
6561         mServices.bringDownDisabledPackageServicesLocked(
6562                 packageName, disabledClasses, userId, false, killProcess, true);
6563
6564         // Clean-up disabled providers.
6565         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6566         mProviderMap.collectPackageProvidersLocked(
6567                 packageName, disabledClasses, true, false, userId, providers);
6568         for (int i = providers.size() - 1; i >= 0; i--) {
6569             removeDyingProviderLocked(null, providers.get(i), true);
6570         }
6571
6572         // Clean-up disabled broadcast receivers.
6573         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6574             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6575                     packageName, disabledClasses, userId, true);
6576         }
6577
6578     }
6579
6580     final boolean clearBroadcastQueueForUserLocked(int userId) {
6581         boolean didSomething = false;
6582         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6583             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6584                     null, null, userId, true);
6585         }
6586         return didSomething;
6587     }
6588
6589     final boolean forceStopPackageLocked(String packageName, int appId,
6590             boolean callerWillRestart, boolean purgeCache, boolean doit,
6591             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6592         int i;
6593
6594         if (userId == UserHandle.USER_ALL && packageName == null) {
6595             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6596         }
6597
6598         if (appId < 0 && packageName != null) {
6599             try {
6600                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6601                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6602             } catch (RemoteException e) {
6603             }
6604         }
6605
6606         if (doit) {
6607             if (packageName != null) {
6608                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6609                         + " user=" + userId + ": " + reason);
6610             } else {
6611                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6612             }
6613
6614             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6615         }
6616
6617         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6618                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6619                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6620
6621         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6622
6623         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6624                 packageName, null, doit, evenPersistent, userId)) {
6625             if (!doit) {
6626                 return true;
6627             }
6628             didSomething = true;
6629         }
6630
6631         if (mServices.bringDownDisabledPackageServicesLocked(
6632                 packageName, null, userId, evenPersistent, true, doit)) {
6633             if (!doit) {
6634                 return true;
6635             }
6636             didSomething = true;
6637         }
6638
6639         if (packageName == null) {
6640             // Remove all sticky broadcasts from this user.
6641             mStickyBroadcasts.remove(userId);
6642         }
6643
6644         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6645         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6646                 userId, providers)) {
6647             if (!doit) {
6648                 return true;
6649             }
6650             didSomething = true;
6651         }
6652         for (i = providers.size() - 1; i >= 0; i--) {
6653             removeDyingProviderLocked(null, providers.get(i), true);
6654         }
6655
6656         // Remove transient permissions granted from/to this package/user
6657         removeUriPermissionsForPackageLocked(packageName, userId, false);
6658
6659         if (doit) {
6660             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6661                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6662                         packageName, null, userId, doit);
6663             }
6664         }
6665
6666         if (packageName == null || uninstalling) {
6667             // Remove pending intents.  For now we only do this when force
6668             // stopping users, because we have some problems when doing this
6669             // for packages -- app widgets are not currently cleaned up for
6670             // such packages, so they can be left with bad pending intents.
6671             if (mIntentSenderRecords.size() > 0) {
6672                 Iterator<WeakReference<PendingIntentRecord>> it
6673                         = mIntentSenderRecords.values().iterator();
6674                 while (it.hasNext()) {
6675                     WeakReference<PendingIntentRecord> wpir = it.next();
6676                     if (wpir == null) {
6677                         it.remove();
6678                         continue;
6679                     }
6680                     PendingIntentRecord pir = wpir.get();
6681                     if (pir == null) {
6682                         it.remove();
6683                         continue;
6684                     }
6685                     if (packageName == null) {
6686                         // Stopping user, remove all objects for the user.
6687                         if (pir.key.userId != userId) {
6688                             // Not the same user, skip it.
6689                             continue;
6690                         }
6691                     } else {
6692                         if (UserHandle.getAppId(pir.uid) != appId) {
6693                             // Different app id, skip it.
6694                             continue;
6695                         }
6696                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6697                             // Different user, skip it.
6698                             continue;
6699                         }
6700                         if (!pir.key.packageName.equals(packageName)) {
6701                             // Different package, skip it.
6702                             continue;
6703                         }
6704                     }
6705                     if (!doit) {
6706                         return true;
6707                     }
6708                     didSomething = true;
6709                     it.remove();
6710                     makeIntentSenderCanceledLocked(pir);
6711                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6712                         pir.key.activity.pendingResults.remove(pir.ref);
6713                     }
6714                 }
6715             }
6716         }
6717
6718         if (doit) {
6719             if (purgeCache && packageName != null) {
6720                 AttributeCache ac = AttributeCache.instance();
6721                 if (ac != null) {
6722                     ac.removePackage(packageName);
6723                 }
6724             }
6725             if (mBooted) {
6726                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6727                 mStackSupervisor.scheduleIdleLocked();
6728             }
6729         }
6730
6731         return didSomething;
6732     }
6733
6734     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6735         return removeProcessNameLocked(name, uid, null);
6736     }
6737
6738     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6739             final ProcessRecord expecting) {
6740         ProcessRecord old = mProcessNames.get(name, uid);
6741         // Only actually remove when the currently recorded value matches the
6742         // record that we expected; if it doesn't match then we raced with a
6743         // newly created process and we don't want to destroy the new one.
6744         if ((expecting == null) || (old == expecting)) {
6745             mProcessNames.remove(name, uid);
6746         }
6747         if (old != null && old.uidRecord != null) {
6748             old.uidRecord.numProcs--;
6749             if (old.uidRecord.numProcs == 0) {
6750                 // No more processes using this uid, tell clients it is gone.
6751                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6752                         "No more processes in " + old.uidRecord);
6753                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6754                 EventLogTags.writeAmUidStopped(uid);
6755                 mActiveUids.remove(uid);
6756                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6757             }
6758             old.uidRecord = null;
6759         }
6760         mIsolatedProcesses.remove(uid);
6761         return old;
6762     }
6763
6764     private final void addProcessNameLocked(ProcessRecord proc) {
6765         // We shouldn't already have a process under this name, but just in case we
6766         // need to clean up whatever may be there now.
6767         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6768         if (old == proc && proc.persistent) {
6769             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6770             Slog.w(TAG, "Re-adding persistent process " + proc);
6771         } else if (old != null) {
6772             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6773         }
6774         UidRecord uidRec = mActiveUids.get(proc.uid);
6775         if (uidRec == null) {
6776             uidRec = new UidRecord(proc.uid);
6777             // This is the first appearance of the uid, report it now!
6778             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6779                     "Creating new process uid: " + uidRec);
6780             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6781                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6782                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6783             }
6784             uidRec.updateHasInternetPermission();
6785             mActiveUids.put(proc.uid, uidRec);
6786             EventLogTags.writeAmUidRunning(uidRec.uid);
6787             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6788         }
6789         proc.uidRecord = uidRec;
6790
6791         // Reset render thread tid if it was already set, so new process can set it again.
6792         proc.renderThreadTid = 0;
6793         uidRec.numProcs++;
6794         mProcessNames.put(proc.processName, proc.uid, proc);
6795         if (proc.isolated) {
6796             mIsolatedProcesses.put(proc.uid, proc);
6797         }
6798     }
6799
6800     boolean removeProcessLocked(ProcessRecord app,
6801             boolean callerWillRestart, boolean allowRestart, String reason) {
6802         final String name = app.processName;
6803         final int uid = app.uid;
6804         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6805             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6806
6807         ProcessRecord old = mProcessNames.get(name, uid);
6808         if (old != app) {
6809             // This process is no longer active, so nothing to do.
6810             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6811             return false;
6812         }
6813         removeProcessNameLocked(name, uid);
6814         if (mHeavyWeightProcess == app) {
6815             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6816                     mHeavyWeightProcess.userId, 0));
6817             mHeavyWeightProcess = null;
6818         }
6819         boolean needRestart = false;
6820         if (app.pid > 0 && app.pid != MY_PID) {
6821             int pid = app.pid;
6822             synchronized (mPidsSelfLocked) {
6823                 mPidsSelfLocked.remove(pid);
6824                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6825             }
6826             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6827             boolean willRestart = false;
6828             if (app.persistent && !app.isolated) {
6829                 if (!callerWillRestart) {
6830                     willRestart = true;
6831                 } else {
6832                     needRestart = true;
6833                 }
6834             }
6835             app.kill(reason, true);
6836             if (app.isolated) {
6837                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6838                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6839             }
6840             handleAppDiedLocked(app, willRestart, allowRestart);
6841             if (willRestart) {
6842                 removeLruProcessLocked(app);
6843                 addAppLocked(app.info, null, false, null /* ABI override */);
6844             }
6845         } else {
6846             mRemovedProcesses.add(app);
6847         }
6848
6849         return needRestart;
6850     }
6851
6852     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6853         cleanupAppInLaunchingProvidersLocked(app, true);
6854         removeProcessLocked(app, false, true, "timeout publishing content providers");
6855     }
6856
6857     private final void processStartTimedOutLocked(ProcessRecord app) {
6858         final int pid = app.pid;
6859         boolean gone = false;
6860         synchronized (mPidsSelfLocked) {
6861             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6862             if (knownApp != null && knownApp.thread == null) {
6863                 mPidsSelfLocked.remove(pid);
6864                 gone = true;
6865             }
6866         }
6867
6868         if (gone) {
6869             Slog.w(TAG, "Process " + app + " failed to attach");
6870             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6871                     pid, app.uid, app.processName);
6872             removeProcessNameLocked(app.processName, app.uid);
6873             if (mHeavyWeightProcess == app) {
6874                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6875                         mHeavyWeightProcess.userId, 0));
6876                 mHeavyWeightProcess = null;
6877             }
6878             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6879             // Take care of any launching providers waiting for this process.
6880             cleanupAppInLaunchingProvidersLocked(app, true);
6881             // Take care of any services that are waiting for the process.
6882             mServices.processStartTimedOutLocked(app);
6883             app.kill("start timeout", true);
6884             if (app.isolated) {
6885                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6886             }
6887             removeLruProcessLocked(app);
6888             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6889                 Slog.w(TAG, "Unattached app died before backup, skipping");
6890                 mHandler.post(new Runnable() {
6891                 @Override
6892                     public void run(){
6893                         try {
6894                             IBackupManager bm = IBackupManager.Stub.asInterface(
6895                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6896                             bm.agentDisconnected(app.info.packageName);
6897                         } catch (RemoteException e) {
6898                             // Can't happen; the backup manager is local
6899                         }
6900                     }
6901                 });
6902             }
6903             if (isPendingBroadcastProcessLocked(pid)) {
6904                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6905                 skipPendingBroadcastLocked(pid);
6906             }
6907         } else {
6908             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6909         }
6910     }
6911
6912     private final boolean attachApplicationLocked(IApplicationThread thread,
6913             int pid) {
6914
6915         // Find the application record that is being attached...  either via
6916         // the pid if we are running in multiple processes, or just pull the
6917         // next app record if we are emulating process with anonymous threads.
6918         ProcessRecord app;
6919         long startTime = SystemClock.uptimeMillis();
6920         if (pid != MY_PID && pid >= 0) {
6921             synchronized (mPidsSelfLocked) {
6922                 app = mPidsSelfLocked.get(pid);
6923             }
6924         } else {
6925             app = null;
6926         }
6927
6928         if (app == null) {
6929             Slog.w(TAG, "No pending application record for pid " + pid
6930                     + " (IApplicationThread " + thread + "); dropping process");
6931             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6932             if (pid > 0 && pid != MY_PID) {
6933                 killProcessQuiet(pid);
6934                 //TODO: killProcessGroup(app.info.uid, pid);
6935             } else {
6936                 try {
6937                     thread.scheduleExit();
6938                 } catch (Exception e) {
6939                     // Ignore exceptions.
6940                 }
6941             }
6942             return false;
6943         }
6944
6945         // If this application record is still attached to a previous
6946         // process, clean it up now.
6947         if (app.thread != null) {
6948             handleAppDiedLocked(app, true, true);
6949         }
6950
6951         // Tell the process all about itself.
6952
6953         if (DEBUG_ALL) Slog.v(
6954                 TAG, "Binding process pid " + pid + " to record " + app);
6955
6956         final String processName = app.processName;
6957         try {
6958             AppDeathRecipient adr = new AppDeathRecipient(
6959                     app, pid, thread);
6960             thread.asBinder().linkToDeath(adr, 0);
6961             app.deathRecipient = adr;
6962         } catch (RemoteException e) {
6963             app.resetPackageList(mProcessStats);
6964             startProcessLocked(app, "link fail", processName);
6965             return false;
6966         }
6967
6968         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6969
6970         app.makeActive(thread, mProcessStats);
6971         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6972         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6973         app.forcingToImportant = null;
6974         updateProcessForegroundLocked(app, false, false);
6975         app.hasShownUi = false;
6976         app.debugging = false;
6977         app.cached = false;
6978         app.killedByAm = false;
6979         app.killed = false;
6980
6981
6982         // We carefully use the same state that PackageManager uses for
6983         // filtering, since we use this flag to decide if we need to install
6984         // providers when user is unlocked later
6985         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6986
6987         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6988
6989         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6990         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6991
6992         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6993             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6994             msg.obj = app;
6995             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6996         }
6997
6998         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6999
7000         if (!normalMode) {
7001             Slog.i(TAG, "Launching preboot mode app: " + app);
7002         }
7003
7004         if (DEBUG_ALL) Slog.v(
7005             TAG, "New app record " + app
7006             + " thread=" + thread.asBinder() + " pid=" + pid);
7007         try {
7008             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7009             if (mDebugApp != null && mDebugApp.equals(processName)) {
7010                 testMode = mWaitForDebugger
7011                     ? ApplicationThreadConstants.DEBUG_WAIT
7012                     : ApplicationThreadConstants.DEBUG_ON;
7013                 app.debugging = true;
7014                 if (mDebugTransient) {
7015                     mDebugApp = mOrigDebugApp;
7016                     mWaitForDebugger = mOrigWaitForDebugger;
7017                 }
7018             }
7019
7020             ProfilerInfo profilerInfo = null;
7021             String preBindAgent = null;
7022             if (mProfileApp != null && mProfileApp.equals(processName)) {
7023                 mProfileProc = app;
7024                 if (mProfilerInfo != null) {
7025                     // Send a profiler info object to the app if either a file is given, or
7026                     // an agent should be loaded at bind-time.
7027                     boolean needsInfo = mProfilerInfo.profileFile != null
7028                             || mProfilerInfo.attachAgentDuringBind;
7029                     profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7030                     if (!mProfilerInfo.attachAgentDuringBind) {
7031                         preBindAgent = mProfilerInfo.agent;
7032                     }
7033                 }
7034             } else if (app.instr != null && app.instr.mProfileFile != null) {
7035                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7036                         null, false);
7037             }
7038
7039             boolean enableTrackAllocation = false;
7040             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7041                 enableTrackAllocation = true;
7042                 mTrackAllocationApp = null;
7043             }
7044
7045             // If the app is being launched for restore or full backup, set it up specially
7046             boolean isRestrictedBackupMode = false;
7047             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7048                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7049                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7050                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7051                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7052             }
7053
7054             if (app.instr != null) {
7055                 notifyPackageUse(app.instr.mClass.getPackageName(),
7056                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7057             }
7058             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7059                     + processName + " with config " + getGlobalConfiguration());
7060             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7061             app.compat = compatibilityInfoForPackageLocked(appInfo);
7062
7063             if (profilerInfo != null && profilerInfo.profileFd != null) {
7064                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7065             }
7066
7067             // We deprecated Build.SERIAL and it is not accessible to
7068             // apps that target the v2 security sandbox. Since access to
7069             // the serial is now behind a permission we push down the value.
7070             String buildSerial = appInfo.targetSandboxVersion < 2
7071                     ? sTheRealBuildSerial : Build.UNKNOWN;
7072
7073             // Check if this is a secondary process that should be incorporated into some
7074             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7075             // stuff above because profiling can currently happen only in the primary
7076             // instrumentation process.)
7077             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7078                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7079                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7080                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7081                         if (aInstr.mTargetProcesses.length == 0) {
7082                             // This is the wildcard mode, where every process brought up for
7083                             // the target instrumentation should be included.
7084                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7085                                 app.instr = aInstr;
7086                                 aInstr.mRunningProcesses.add(app);
7087                             }
7088                         } else {
7089                             for (String proc : aInstr.mTargetProcesses) {
7090                                 if (proc.equals(app.processName)) {
7091                                     app.instr = aInstr;
7092                                     aInstr.mRunningProcesses.add(app);
7093                                     break;
7094                                 }
7095                             }
7096                         }
7097                     }
7098                 }
7099             }
7100
7101             // If we were asked to attach an agent on startup, do so now, before we're binding
7102             // application code.
7103             if (preBindAgent != null) {
7104                 thread.attachAgent(preBindAgent);
7105             }
7106
7107             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7108             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7109             if (app.instr != null) {
7110                 thread.bindApplication(processName, appInfo, providers,
7111                         app.instr.mClass,
7112                         profilerInfo, app.instr.mArguments,
7113                         app.instr.mWatcher,
7114                         app.instr.mUiAutomationConnection, testMode,
7115                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7116                         isRestrictedBackupMode || !normalMode, app.persistent,
7117                         new Configuration(getGlobalConfiguration()), app.compat,
7118                         getCommonServicesLocked(app.isolated),
7119                         mCoreSettingsObserver.getCoreSettingsLocked(),
7120                         buildSerial);
7121             } else {
7122                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7123                         null, null, null, testMode,
7124                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7125                         isRestrictedBackupMode || !normalMode, app.persistent,
7126                         new Configuration(getGlobalConfiguration()), app.compat,
7127                         getCommonServicesLocked(app.isolated),
7128                         mCoreSettingsObserver.getCoreSettingsLocked(),
7129                         buildSerial);
7130             }
7131
7132             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7133             updateLruProcessLocked(app, false, null);
7134             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7135             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7136         } catch (Exception e) {
7137             // todo: Yikes!  What should we do?  For now we will try to
7138             // start another process, but that could easily get us in
7139             // an infinite loop of restarting processes...
7140             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7141
7142             app.resetPackageList(mProcessStats);
7143             app.unlinkDeathRecipient();
7144             startProcessLocked(app, "bind fail", processName);
7145             return false;
7146         }
7147
7148         // Remove this record from the list of starting applications.
7149         mPersistentStartingProcesses.remove(app);
7150         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7151                 "Attach application locked removing on hold: " + app);
7152         mProcessesOnHold.remove(app);
7153
7154         boolean badApp = false;
7155         boolean didSomething = false;
7156
7157         // See if the top visible activity is waiting to run in this process...
7158         if (normalMode) {
7159             try {
7160                 if (mStackSupervisor.attachApplicationLocked(app)) {
7161                     didSomething = true;
7162                 }
7163             } catch (Exception e) {
7164                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7165                 badApp = true;
7166             }
7167         }
7168
7169         // Find any services that should be running in this process...
7170         if (!badApp) {
7171             try {
7172                 didSomething |= mServices.attachApplicationLocked(app, processName);
7173                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7174             } catch (Exception e) {
7175                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7176                 badApp = true;
7177             }
7178         }
7179
7180         // Check if a next-broadcast receiver is in this process...
7181         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7182             try {
7183                 didSomething |= sendPendingBroadcastsLocked(app);
7184                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7185             } catch (Exception e) {
7186                 // If the app died trying to launch the receiver we declare it 'bad'
7187                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7188                 badApp = true;
7189             }
7190         }
7191
7192         // Check whether the next backup agent is in this process...
7193         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7194             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7195                     "New app is backup target, launching agent for " + app);
7196             notifyPackageUse(mBackupTarget.appInfo.packageName,
7197                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7198             try {
7199                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7200                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7201                         mBackupTarget.backupMode);
7202             } catch (Exception e) {
7203                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7204                 badApp = true;
7205             }
7206         }
7207
7208         if (badApp) {
7209             app.kill("error during init", true);
7210             handleAppDiedLocked(app, false, true);
7211             return false;
7212         }
7213
7214         if (!didSomething) {
7215             updateOomAdjLocked();
7216             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7217         }
7218
7219         return true;
7220     }
7221
7222     @Override
7223     public final void attachApplication(IApplicationThread thread) {
7224         synchronized (this) {
7225             int callingPid = Binder.getCallingPid();
7226             final long origId = Binder.clearCallingIdentity();
7227             attachApplicationLocked(thread, callingPid);
7228             Binder.restoreCallingIdentity(origId);
7229         }
7230     }
7231
7232     @Override
7233     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7234         final long origId = Binder.clearCallingIdentity();
7235         synchronized (this) {
7236             ActivityStack stack = ActivityRecord.getStackLocked(token);
7237             if (stack != null) {
7238                 ActivityRecord r =
7239                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7240                                 false /* processPausingActivities */, config);
7241                 if (stopProfiling) {
7242                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7243                         clearProfilerLocked();
7244                     }
7245                 }
7246             }
7247         }
7248         Binder.restoreCallingIdentity(origId);
7249     }
7250
7251     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7252         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7253                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7254     }
7255
7256     void enableScreenAfterBoot() {
7257         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7258                 SystemClock.uptimeMillis());
7259         mWindowManager.enableScreenAfterBoot();
7260
7261         synchronized (this) {
7262             updateEventDispatchingLocked();
7263         }
7264     }
7265
7266     @Override
7267     public void showBootMessage(final CharSequence msg, final boolean always) {
7268         if (Binder.getCallingUid() != myUid()) {
7269             throw new SecurityException();
7270         }
7271         mWindowManager.showBootMessage(msg, always);
7272     }
7273
7274     @Override
7275     public void keyguardGoingAway(int flags) {
7276         enforceNotIsolatedCaller("keyguardGoingAway");
7277         final long token = Binder.clearCallingIdentity();
7278         try {
7279             synchronized (this) {
7280                 mKeyguardController.keyguardGoingAway(flags);
7281             }
7282         } finally {
7283             Binder.restoreCallingIdentity(token);
7284         }
7285     }
7286
7287     /**
7288      * @return whther the keyguard is currently locked.
7289      */
7290     boolean isKeyguardLocked() {
7291         return mKeyguardController.isKeyguardLocked();
7292     }
7293
7294     final void finishBooting() {
7295         synchronized (this) {
7296             if (!mBootAnimationComplete) {
7297                 mCallFinishBooting = true;
7298                 return;
7299             }
7300             mCallFinishBooting = false;
7301         }
7302
7303         ArraySet<String> completedIsas = new ArraySet<String>();
7304         for (String abi : Build.SUPPORTED_ABIS) {
7305             zygoteProcess.establishZygoteConnectionForAbi(abi);
7306             final String instructionSet = VMRuntime.getInstructionSet(abi);
7307             if (!completedIsas.contains(instructionSet)) {
7308                 try {
7309                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7310                 } catch (InstallerException e) {
7311                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7312                             e.getMessage() +")");
7313                 }
7314                 completedIsas.add(instructionSet);
7315             }
7316         }
7317
7318         IntentFilter pkgFilter = new IntentFilter();
7319         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7320         pkgFilter.addDataScheme("package");
7321         mContext.registerReceiver(new BroadcastReceiver() {
7322             @Override
7323             public void onReceive(Context context, Intent intent) {
7324                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7325                 if (pkgs != null) {
7326                     for (String pkg : pkgs) {
7327                         synchronized (ActivityManagerService.this) {
7328                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7329                                     0, "query restart")) {
7330                                 setResultCode(Activity.RESULT_OK);
7331                                 return;
7332                             }
7333                         }
7334                     }
7335                 }
7336             }
7337         }, pkgFilter);
7338
7339         IntentFilter dumpheapFilter = new IntentFilter();
7340         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7341         mContext.registerReceiver(new BroadcastReceiver() {
7342             @Override
7343             public void onReceive(Context context, Intent intent) {
7344                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7345                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7346                 } else {
7347                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7348                 }
7349             }
7350         }, dumpheapFilter);
7351
7352         // Let system services know.
7353         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7354
7355         synchronized (this) {
7356             // Ensure that any processes we had put on hold are now started
7357             // up.
7358             final int NP = mProcessesOnHold.size();
7359             if (NP > 0) {
7360                 ArrayList<ProcessRecord> procs =
7361                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7362                 for (int ip=0; ip<NP; ip++) {
7363                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7364                             + procs.get(ip));
7365                     startProcessLocked(procs.get(ip), "on-hold", null);
7366                 }
7367             }
7368
7369             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7370                 // Start looking for apps that are abusing wake locks.
7371                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7372                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7373                 // Tell anyone interested that we are done booting!
7374                 SystemProperties.set("sys.boot_completed", "1");
7375
7376                 // And trigger dev.bootcomplete if we are not showing encryption progress
7377                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7378                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7379                     SystemProperties.set("dev.bootcomplete", "1");
7380                 }
7381                 mUserController.sendBootCompletedLocked(
7382                         new IIntentReceiver.Stub() {
7383                             @Override
7384                             public void performReceive(Intent intent, int resultCode,
7385                                     String data, Bundle extras, boolean ordered,
7386                                     boolean sticky, int sendingUser) {
7387                                 synchronized (ActivityManagerService.this) {
7388                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7389                                             true, false);
7390                                 }
7391                             }
7392                         });
7393                 scheduleStartProfilesLocked();
7394             }
7395         }
7396     }
7397
7398     @Override
7399     public void bootAnimationComplete() {
7400         final boolean callFinishBooting;
7401         synchronized (this) {
7402             callFinishBooting = mCallFinishBooting;
7403             mBootAnimationComplete = true;
7404         }
7405         if (callFinishBooting) {
7406             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7407             finishBooting();
7408             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7409         }
7410     }
7411
7412     final void ensureBootCompleted() {
7413         boolean booting;
7414         boolean enableScreen;
7415         synchronized (this) {
7416             booting = mBooting;
7417             mBooting = false;
7418             enableScreen = !mBooted;
7419             mBooted = true;
7420         }
7421
7422         if (booting) {
7423             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7424             finishBooting();
7425             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7426         }
7427
7428         if (enableScreen) {
7429             enableScreenAfterBoot();
7430         }
7431     }
7432
7433     @Override
7434     public final void activityResumed(IBinder token) {
7435         final long origId = Binder.clearCallingIdentity();
7436         synchronized(this) {
7437             ActivityRecord.activityResumedLocked(token);
7438             mWindowManager.notifyAppResumedFinished(token);
7439         }
7440         Binder.restoreCallingIdentity(origId);
7441     }
7442
7443     @Override
7444     public final void activityPaused(IBinder token) {
7445         final long origId = Binder.clearCallingIdentity();
7446         synchronized(this) {
7447             ActivityStack stack = ActivityRecord.getStackLocked(token);
7448             if (stack != null) {
7449                 stack.activityPausedLocked(token, false);
7450             }
7451         }
7452         Binder.restoreCallingIdentity(origId);
7453     }
7454
7455     @Override
7456     public final void activityStopped(IBinder token, Bundle icicle,
7457             PersistableBundle persistentState, CharSequence description) {
7458         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7459
7460         // Refuse possible leaked file descriptors
7461         if (icicle != null && icicle.hasFileDescriptors()) {
7462             throw new IllegalArgumentException("File descriptors passed in Bundle");
7463         }
7464
7465         final long origId = Binder.clearCallingIdentity();
7466
7467         synchronized (this) {
7468             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7469             if (r != null) {
7470                 r.activityStoppedLocked(icicle, persistentState, description);
7471             }
7472         }
7473
7474         trimApplications();
7475
7476         Binder.restoreCallingIdentity(origId);
7477     }
7478
7479     @Override
7480     public final void activityDestroyed(IBinder token) {
7481         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7482         synchronized (this) {
7483             ActivityStack stack = ActivityRecord.getStackLocked(token);
7484             if (stack != null) {
7485                 stack.activityDestroyedLocked(token, "activityDestroyed");
7486             }
7487         }
7488     }
7489
7490     @Override
7491     public final void activityRelaunched(IBinder token) {
7492         final long origId = Binder.clearCallingIdentity();
7493         synchronized (this) {
7494             mStackSupervisor.activityRelaunchedLocked(token);
7495         }
7496         Binder.restoreCallingIdentity(origId);
7497     }
7498
7499     @Override
7500     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7501             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7502         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7503                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7504         synchronized (this) {
7505             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7506             if (record == null) {
7507                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7508                         + "found for: " + token);
7509             }
7510             record.setSizeConfigurations(horizontalSizeConfiguration,
7511                     verticalSizeConfigurations, smallestSizeConfigurations);
7512         }
7513     }
7514
7515     @Override
7516     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7517         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7518     }
7519
7520     @Override
7521     public final void notifyEnterAnimationComplete(IBinder token) {
7522         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7523     }
7524
7525     @Override
7526     public String getCallingPackage(IBinder token) {
7527         synchronized (this) {
7528             ActivityRecord r = getCallingRecordLocked(token);
7529             return r != null ? r.info.packageName : null;
7530         }
7531     }
7532
7533     @Override
7534     public ComponentName getCallingActivity(IBinder token) {
7535         synchronized (this) {
7536             ActivityRecord r = getCallingRecordLocked(token);
7537             return r != null ? r.intent.getComponent() : null;
7538         }
7539     }
7540
7541     private ActivityRecord getCallingRecordLocked(IBinder token) {
7542         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7543         if (r == null) {
7544             return null;
7545         }
7546         return r.resultTo;
7547     }
7548
7549     @Override
7550     public ComponentName getActivityClassForToken(IBinder token) {
7551         synchronized(this) {
7552             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7553             if (r == null) {
7554                 return null;
7555             }
7556             return r.intent.getComponent();
7557         }
7558     }
7559
7560     @Override
7561     public String getPackageForToken(IBinder token) {
7562         synchronized(this) {
7563             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7564             if (r == null) {
7565                 return null;
7566             }
7567             return r.packageName;
7568         }
7569     }
7570
7571     @Override
7572     public boolean isRootVoiceInteraction(IBinder token) {
7573         synchronized(this) {
7574             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7575             if (r == null) {
7576                 return false;
7577             }
7578             return r.rootVoiceInteraction;
7579         }
7580     }
7581
7582     @Override
7583     public IIntentSender getIntentSender(int type,
7584             String packageName, IBinder token, String resultWho,
7585             int requestCode, Intent[] intents, String[] resolvedTypes,
7586             int flags, Bundle bOptions, int userId) {
7587         enforceNotIsolatedCaller("getIntentSender");
7588         // Refuse possible leaked file descriptors
7589         if (intents != null) {
7590             if (intents.length < 1) {
7591                 throw new IllegalArgumentException("Intents array length must be >= 1");
7592             }
7593             for (int i=0; i<intents.length; i++) {
7594                 Intent intent = intents[i];
7595                 if (intent != null) {
7596                     if (intent.hasFileDescriptors()) {
7597                         throw new IllegalArgumentException("File descriptors passed in Intent");
7598                     }
7599                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7600                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7601                         throw new IllegalArgumentException(
7602                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7603                     }
7604                     intents[i] = new Intent(intent);
7605                 }
7606             }
7607             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7608                 throw new IllegalArgumentException(
7609                         "Intent array length does not match resolvedTypes length");
7610             }
7611         }
7612         if (bOptions != null) {
7613             if (bOptions.hasFileDescriptors()) {
7614                 throw new IllegalArgumentException("File descriptors passed in options");
7615             }
7616         }
7617
7618         synchronized(this) {
7619             int callingUid = Binder.getCallingUid();
7620             int origUserId = userId;
7621             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7622                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7623                     ALLOW_NON_FULL, "getIntentSender", null);
7624             if (origUserId == UserHandle.USER_CURRENT) {
7625                 // We don't want to evaluate this until the pending intent is
7626                 // actually executed.  However, we do want to always do the
7627                 // security checking for it above.
7628                 userId = UserHandle.USER_CURRENT;
7629             }
7630             try {
7631                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7632                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7633                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7634                     if (!UserHandle.isSameApp(callingUid, uid)) {
7635                         String msg = "Permission Denial: getIntentSender() from pid="
7636                             + Binder.getCallingPid()
7637                             + ", uid=" + Binder.getCallingUid()
7638                             + ", (need uid=" + uid + ")"
7639                             + " is not allowed to send as package " + packageName;
7640                         Slog.w(TAG, msg);
7641                         throw new SecurityException(msg);
7642                     }
7643                 }
7644
7645                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7646                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7647
7648             } catch (RemoteException e) {
7649                 throw new SecurityException(e);
7650             }
7651         }
7652     }
7653
7654     IIntentSender getIntentSenderLocked(int type, String packageName,
7655             int callingUid, int userId, IBinder token, String resultWho,
7656             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7657             Bundle bOptions) {
7658         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7659         ActivityRecord activity = null;
7660         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7661             activity = ActivityRecord.isInStackLocked(token);
7662             if (activity == null) {
7663                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7664                 return null;
7665             }
7666             if (activity.finishing) {
7667                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7668                 return null;
7669             }
7670         }
7671
7672         // We're going to be splicing together extras before sending, so we're
7673         // okay poking into any contained extras.
7674         if (intents != null) {
7675             for (int i = 0; i < intents.length; i++) {
7676                 intents[i].setDefusable(true);
7677             }
7678         }
7679         Bundle.setDefusable(bOptions, true);
7680
7681         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7682         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7683         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7684         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7685                 |PendingIntent.FLAG_UPDATE_CURRENT);
7686
7687         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7688                 type, packageName, activity, resultWho,
7689                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7690         WeakReference<PendingIntentRecord> ref;
7691         ref = mIntentSenderRecords.get(key);
7692         PendingIntentRecord rec = ref != null ? ref.get() : null;
7693         if (rec != null) {
7694             if (!cancelCurrent) {
7695                 if (updateCurrent) {
7696                     if (rec.key.requestIntent != null) {
7697                         rec.key.requestIntent.replaceExtras(intents != null ?
7698                                 intents[intents.length - 1] : null);
7699                     }
7700                     if (intents != null) {
7701                         intents[intents.length-1] = rec.key.requestIntent;
7702                         rec.key.allIntents = intents;
7703                         rec.key.allResolvedTypes = resolvedTypes;
7704                     } else {
7705                         rec.key.allIntents = null;
7706                         rec.key.allResolvedTypes = null;
7707                     }
7708                 }
7709                 return rec;
7710             }
7711             makeIntentSenderCanceledLocked(rec);
7712             mIntentSenderRecords.remove(key);
7713         }
7714         if (noCreate) {
7715             return rec;
7716         }
7717         rec = new PendingIntentRecord(this, key, callingUid);
7718         mIntentSenderRecords.put(key, rec.ref);
7719         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7720             if (activity.pendingResults == null) {
7721                 activity.pendingResults
7722                         = new HashSet<WeakReference<PendingIntentRecord>>();
7723             }
7724             activity.pendingResults.add(rec.ref);
7725         }
7726         return rec;
7727     }
7728
7729     @Override
7730     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7731             Intent intent, String resolvedType,
7732             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7733         if (target instanceof PendingIntentRecord) {
7734             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7735                     whitelistToken, finishedReceiver, requiredPermission, options);
7736         } else {
7737             if (intent == null) {
7738                 // Weird case: someone has given us their own custom IIntentSender, and now
7739                 // they have someone else trying to send to it but of course this isn't
7740                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7741                 // supplying an Intent... but we never want to dispatch a null Intent to
7742                 // a receiver, so um...  let's make something up.
7743                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7744                 intent = new Intent(Intent.ACTION_MAIN);
7745             }
7746             try {
7747                 target.send(code, intent, resolvedType, whitelistToken, null,
7748                         requiredPermission, options);
7749             } catch (RemoteException e) {
7750             }
7751             // Platform code can rely on getting a result back when the send is done, but if
7752             // this intent sender is from outside of the system we can't rely on it doing that.
7753             // So instead we don't give it the result receiver, and instead just directly
7754             // report the finish immediately.
7755             if (finishedReceiver != null) {
7756                 try {
7757                     finishedReceiver.performReceive(intent, 0,
7758                             null, null, false, false, UserHandle.getCallingUserId());
7759                 } catch (RemoteException e) {
7760                 }
7761             }
7762             return 0;
7763         }
7764     }
7765
7766     @Override
7767     public void cancelIntentSender(IIntentSender sender) {
7768         if (!(sender instanceof PendingIntentRecord)) {
7769             return;
7770         }
7771         synchronized(this) {
7772             PendingIntentRecord rec = (PendingIntentRecord)sender;
7773             try {
7774                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7775                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7776                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7777                     String msg = "Permission Denial: cancelIntentSender() from pid="
7778                         + Binder.getCallingPid()
7779                         + ", uid=" + Binder.getCallingUid()
7780                         + " is not allowed to cancel package "
7781                         + rec.key.packageName;
7782                     Slog.w(TAG, msg);
7783                     throw new SecurityException(msg);
7784                 }
7785             } catch (RemoteException e) {
7786                 throw new SecurityException(e);
7787             }
7788             cancelIntentSenderLocked(rec, true);
7789         }
7790     }
7791
7792     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7793         makeIntentSenderCanceledLocked(rec);
7794         mIntentSenderRecords.remove(rec.key);
7795         if (cleanActivity && rec.key.activity != null) {
7796             rec.key.activity.pendingResults.remove(rec.ref);
7797         }
7798     }
7799
7800     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7801         rec.canceled = true;
7802         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7803         if (callbacks != null) {
7804             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7805         }
7806     }
7807
7808     @Override
7809     public String getPackageForIntentSender(IIntentSender pendingResult) {
7810         if (!(pendingResult instanceof PendingIntentRecord)) {
7811             return null;
7812         }
7813         try {
7814             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7815             return res.key.packageName;
7816         } catch (ClassCastException e) {
7817         }
7818         return null;
7819     }
7820
7821     @Override
7822     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7823         if (!(sender instanceof PendingIntentRecord)) {
7824             return;
7825         }
7826         synchronized(this) {
7827             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7828         }
7829     }
7830
7831     @Override
7832     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7833             IResultReceiver receiver) {
7834         if (!(sender instanceof PendingIntentRecord)) {
7835             return;
7836         }
7837         synchronized(this) {
7838             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7839         }
7840     }
7841
7842     @Override
7843     public int getUidForIntentSender(IIntentSender sender) {
7844         if (sender instanceof PendingIntentRecord) {
7845             try {
7846                 PendingIntentRecord res = (PendingIntentRecord)sender;
7847                 return res.uid;
7848             } catch (ClassCastException e) {
7849             }
7850         }
7851         return -1;
7852     }
7853
7854     @Override
7855     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7856         if (!(pendingResult instanceof PendingIntentRecord)) {
7857             return false;
7858         }
7859         try {
7860             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7861             if (res.key.allIntents == null) {
7862                 return false;
7863             }
7864             for (int i=0; i<res.key.allIntents.length; i++) {
7865                 Intent intent = res.key.allIntents[i];
7866                 if (intent.getPackage() != null && intent.getComponent() != null) {
7867                     return false;
7868                 }
7869             }
7870             return true;
7871         } catch (ClassCastException e) {
7872         }
7873         return false;
7874     }
7875
7876     @Override
7877     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7878         if (!(pendingResult instanceof PendingIntentRecord)) {
7879             return false;
7880         }
7881         try {
7882             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7883             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7884                 return true;
7885             }
7886             return false;
7887         } catch (ClassCastException e) {
7888         }
7889         return false;
7890     }
7891
7892     @Override
7893     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7894         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7895                 "getIntentForIntentSender()");
7896         if (!(pendingResult instanceof PendingIntentRecord)) {
7897             return null;
7898         }
7899         try {
7900             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7901             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7902         } catch (ClassCastException e) {
7903         }
7904         return null;
7905     }
7906
7907     @Override
7908     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7909         if (!(pendingResult instanceof PendingIntentRecord)) {
7910             return null;
7911         }
7912         try {
7913             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7914             synchronized (this) {
7915                 return getTagForIntentSenderLocked(res, prefix);
7916             }
7917         } catch (ClassCastException e) {
7918         }
7919         return null;
7920     }
7921
7922     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7923         final Intent intent = res.key.requestIntent;
7924         if (intent != null) {
7925             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7926                     || res.lastTagPrefix.equals(prefix))) {
7927                 return res.lastTag;
7928             }
7929             res.lastTagPrefix = prefix;
7930             final StringBuilder sb = new StringBuilder(128);
7931             if (prefix != null) {
7932                 sb.append(prefix);
7933             }
7934             if (intent.getAction() != null) {
7935                 sb.append(intent.getAction());
7936             } else if (intent.getComponent() != null) {
7937                 intent.getComponent().appendShortString(sb);
7938             } else {
7939                 sb.append("?");
7940             }
7941             return res.lastTag = sb.toString();
7942         }
7943         return null;
7944     }
7945
7946     @Override
7947     public void setProcessLimit(int max) {
7948         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7949                 "setProcessLimit()");
7950         synchronized (this) {
7951             mConstants.setOverrideMaxCachedProcesses(max);
7952         }
7953         trimApplications();
7954     }
7955
7956     @Override
7957     public int getProcessLimit() {
7958         synchronized (this) {
7959             return mConstants.getOverrideMaxCachedProcesses();
7960         }
7961     }
7962
7963     void importanceTokenDied(ImportanceToken token) {
7964         synchronized (ActivityManagerService.this) {
7965             synchronized (mPidsSelfLocked) {
7966                 ImportanceToken cur
7967                     = mImportantProcesses.get(token.pid);
7968                 if (cur != token) {
7969                     return;
7970                 }
7971                 mImportantProcesses.remove(token.pid);
7972                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7973                 if (pr == null) {
7974                     return;
7975                 }
7976                 pr.forcingToImportant = null;
7977                 updateProcessForegroundLocked(pr, false, false);
7978             }
7979             updateOomAdjLocked();
7980         }
7981     }
7982
7983     @Override
7984     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7985         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7986                 "setProcessImportant()");
7987         synchronized(this) {
7988             boolean changed = false;
7989
7990             synchronized (mPidsSelfLocked) {
7991                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7992                 if (pr == null && isForeground) {
7993                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7994                     return;
7995                 }
7996                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7997                 if (oldToken != null) {
7998                     oldToken.token.unlinkToDeath(oldToken, 0);
7999                     mImportantProcesses.remove(pid);
8000                     if (pr != null) {
8001                         pr.forcingToImportant = null;
8002                     }
8003                     changed = true;
8004                 }
8005                 if (isForeground && token != null) {
8006                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8007                         @Override
8008                         public void binderDied() {
8009                             importanceTokenDied(this);
8010                         }
8011                     };
8012                     try {
8013                         token.linkToDeath(newToken, 0);
8014                         mImportantProcesses.put(pid, newToken);
8015                         pr.forcingToImportant = newToken;
8016                         changed = true;
8017                     } catch (RemoteException e) {
8018                         // If the process died while doing this, we will later
8019                         // do the cleanup with the process death link.
8020                     }
8021                 }
8022             }
8023
8024             if (changed) {
8025                 updateOomAdjLocked();
8026             }
8027         }
8028     }
8029
8030     @Override
8031     public boolean isAppForeground(int uid) throws RemoteException {
8032         synchronized (this) {
8033             UidRecord uidRec = mActiveUids.get(uid);
8034             if (uidRec == null || uidRec.idle) {
8035                 return false;
8036             }
8037             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8038         }
8039     }
8040
8041     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8042     // be guarded by permission checking.
8043     int getUidState(int uid) {
8044         synchronized (this) {
8045             return getUidStateLocked(uid);
8046         }
8047     }
8048
8049     int getUidStateLocked(int uid) {
8050         UidRecord uidRec = mActiveUids.get(uid);
8051         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8052     }
8053
8054     @Override
8055     public boolean isInMultiWindowMode(IBinder token) {
8056         final long origId = Binder.clearCallingIdentity();
8057         try {
8058             synchronized(this) {
8059                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8060                 if (r == null) {
8061                     return false;
8062                 }
8063                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8064                 return !r.getTask().mFullscreen;
8065             }
8066         } finally {
8067             Binder.restoreCallingIdentity(origId);
8068         }
8069     }
8070
8071     @Override
8072     public boolean isInPictureInPictureMode(IBinder token) {
8073         final long origId = Binder.clearCallingIdentity();
8074         try {
8075             synchronized(this) {
8076                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8077             }
8078         } finally {
8079             Binder.restoreCallingIdentity(origId);
8080         }
8081     }
8082
8083     private boolean isInPictureInPictureMode(ActivityRecord r) {
8084         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8085                 r.getStack().isInStackLocked(r) == null) {
8086             return false;
8087         }
8088
8089         // If we are animating to fullscreen then we have already dispatched the PIP mode
8090         // changed, so we should reflect that check here as well.
8091         final PinnedActivityStack stack = r.getStack();
8092         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8093         return !windowController.isAnimatingBoundsToFullscreen();
8094     }
8095
8096     @Override
8097     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8098         final long origId = Binder.clearCallingIdentity();
8099         try {
8100             synchronized(this) {
8101                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8102                         "enterPictureInPictureMode", token, params);
8103
8104                 // If the activity is already in picture in picture mode, then just return early
8105                 if (isInPictureInPictureMode(r)) {
8106                     return true;
8107                 }
8108
8109                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8110                 // point, if it is
8111                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8112                         false /* beforeStopping */)) {
8113                     return false;
8114                 }
8115
8116                 final Runnable enterPipRunnable = () -> {
8117                     // Only update the saved args from the args that are set
8118                     r.pictureInPictureArgs.copyOnlySet(params);
8119                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8120                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8121                     // Adjust the source bounds by the insets for the transition down
8122                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8123                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8124                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8125                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8126                     stack.setPictureInPictureAspectRatio(aspectRatio);
8127                     stack.setPictureInPictureActions(actions);
8128
8129                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8130                             r.supportsEnterPipOnTaskSwitch);
8131                     logPictureInPictureArgs(params);
8132                 };
8133
8134                 if (isKeyguardLocked()) {
8135                     // If the keyguard is showing or occluded, then try and dismiss it before
8136                     // entering picture-in-picture (this will prompt the user to authenticate if the
8137                     // device is currently locked).
8138                     try {
8139                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8140                             @Override
8141                             public void onDismissError() throws RemoteException {
8142                                 // Do nothing
8143                             }
8144
8145                             @Override
8146                             public void onDismissSucceeded() throws RemoteException {
8147                                 mHandler.post(enterPipRunnable);
8148                             }
8149
8150                             @Override
8151                             public void onDismissCancelled() throws RemoteException {
8152                                 // Do nothing
8153                             }
8154                         });
8155                     } catch (RemoteException e) {
8156                         // Local call
8157                     }
8158                 } else {
8159                     // Enter picture in picture immediately otherwise
8160                     enterPipRunnable.run();
8161                 }
8162                 return true;
8163             }
8164         } finally {
8165             Binder.restoreCallingIdentity(origId);
8166         }
8167     }
8168
8169     @Override
8170     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8171         final long origId = Binder.clearCallingIdentity();
8172         try {
8173             synchronized(this) {
8174                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8175                         "setPictureInPictureParams", token, params);
8176
8177                 // Only update the saved args from the args that are set
8178                 r.pictureInPictureArgs.copyOnlySet(params);
8179                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8180                     // If the activity is already in picture-in-picture, update the pinned stack now
8181                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8182                     // be used the next time the activity enters PiP
8183                     final PinnedActivityStack stack = r.getStack();
8184                     if (!stack.isAnimatingBoundsToFullscreen()) {
8185                         stack.setPictureInPictureAspectRatio(
8186                                 r.pictureInPictureArgs.getAspectRatio());
8187                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8188                     }
8189                 }
8190                 logPictureInPictureArgs(params);
8191             }
8192         } finally {
8193             Binder.restoreCallingIdentity(origId);
8194         }
8195     }
8196
8197     @Override
8198     public int getMaxNumPictureInPictureActions(IBinder token) {
8199         // Currently, this is a static constant, but later, we may change this to be dependent on
8200         // the context of the activity
8201         return 3;
8202     }
8203
8204     private void logPictureInPictureArgs(PictureInPictureParams params) {
8205         if (params.hasSetActions()) {
8206             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8207                     params.getActions().size());
8208         }
8209         if (params.hasSetAspectRatio()) {
8210             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8211             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8212             MetricsLogger.action(lm);
8213         }
8214     }
8215
8216     /**
8217      * Checks the state of the system and the activity associated with the given {@param token} to
8218      * verify that picture-in-picture is supported for that activity.
8219      *
8220      * @return the activity record for the given {@param token} if all the checks pass.
8221      */
8222     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8223             IBinder token, PictureInPictureParams params) {
8224         if (!mSupportsPictureInPicture) {
8225             throw new IllegalStateException(caller
8226                     + ": Device doesn't support picture-in-picture mode.");
8227         }
8228
8229         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8230         if (r == null) {
8231             throw new IllegalStateException(caller
8232                     + ": Can't find activity for token=" + token);
8233         }
8234
8235         if (!r.supportsPictureInPicture()) {
8236             throw new IllegalStateException(caller
8237                     + ": Current activity does not support picture-in-picture.");
8238         }
8239
8240         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8241             throw new IllegalStateException(caller
8242                     + ": Activities on the home, assistant, or recents stack not supported");
8243         }
8244
8245         if (params.hasSetAspectRatio()
8246                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8247                         params.getAspectRatio())) {
8248             final float minAspectRatio = mContext.getResources().getFloat(
8249                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8250             final float maxAspectRatio = mContext.getResources().getFloat(
8251                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8252             throw new IllegalArgumentException(String.format(caller
8253                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8254                             minAspectRatio, maxAspectRatio));
8255         }
8256
8257         // Truncate the number of actions if necessary
8258         params.truncateActions(getMaxNumPictureInPictureActions(token));
8259
8260         return r;
8261     }
8262
8263     // =========================================================
8264     // PROCESS INFO
8265     // =========================================================
8266
8267     static class ProcessInfoService extends IProcessInfoService.Stub {
8268         final ActivityManagerService mActivityManagerService;
8269         ProcessInfoService(ActivityManagerService activityManagerService) {
8270             mActivityManagerService = activityManagerService;
8271         }
8272
8273         @Override
8274         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8275             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8276                     /*in*/ pids, /*out*/ states, null);
8277         }
8278
8279         @Override
8280         public void getProcessStatesAndOomScoresFromPids(
8281                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8282             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8283                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8284         }
8285     }
8286
8287     /**
8288      * For each PID in the given input array, write the current process state
8289      * for that process into the states array, or -1 to indicate that no
8290      * process with the given PID exists. If scores array is provided, write
8291      * the oom score for the process into the scores array, with INVALID_ADJ
8292      * indicating the PID doesn't exist.
8293      */
8294     public void getProcessStatesAndOomScoresForPIDs(
8295             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8296         if (scores != null) {
8297             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8298                     "getProcessStatesAndOomScoresForPIDs()");
8299         }
8300
8301         if (pids == null) {
8302             throw new NullPointerException("pids");
8303         } else if (states == null) {
8304             throw new NullPointerException("states");
8305         } else if (pids.length != states.length) {
8306             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8307         } else if (scores != null && pids.length != scores.length) {
8308             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8309         }
8310
8311         synchronized (mPidsSelfLocked) {
8312             for (int i = 0; i < pids.length; i++) {
8313                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8314                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8315                         pr.curProcState;
8316                 if (scores != null) {
8317                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8318                 }
8319             }
8320         }
8321     }
8322
8323     // =========================================================
8324     // PERMISSIONS
8325     // =========================================================
8326
8327     static class PermissionController extends IPermissionController.Stub {
8328         ActivityManagerService mActivityManagerService;
8329         PermissionController(ActivityManagerService activityManagerService) {
8330             mActivityManagerService = activityManagerService;
8331         }
8332
8333         @Override
8334         public boolean checkPermission(String permission, int pid, int uid) {
8335             return mActivityManagerService.checkPermission(permission, pid,
8336                     uid) == PackageManager.PERMISSION_GRANTED;
8337         }
8338
8339         @Override
8340         public String[] getPackagesForUid(int uid) {
8341             return mActivityManagerService.mContext.getPackageManager()
8342                     .getPackagesForUid(uid);
8343         }
8344
8345         @Override
8346         public boolean isRuntimePermission(String permission) {
8347             try {
8348                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8349                         .getPermissionInfo(permission, 0);
8350                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8351                         == PermissionInfo.PROTECTION_DANGEROUS;
8352             } catch (NameNotFoundException nnfe) {
8353                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8354             }
8355             return false;
8356         }
8357     }
8358
8359     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8360         @Override
8361         public int checkComponentPermission(String permission, int pid, int uid,
8362                 int owningUid, boolean exported) {
8363             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8364                     owningUid, exported);
8365         }
8366
8367         @Override
8368         public Object getAMSLock() {
8369             return ActivityManagerService.this;
8370         }
8371     }
8372
8373     /**
8374      * This can be called with or without the global lock held.
8375      */
8376     int checkComponentPermission(String permission, int pid, int uid,
8377             int owningUid, boolean exported) {
8378         if (pid == MY_PID) {
8379             return PackageManager.PERMISSION_GRANTED;
8380         }
8381         return ActivityManager.checkComponentPermission(permission, uid,
8382                 owningUid, exported);
8383     }
8384
8385     /**
8386      * As the only public entry point for permissions checking, this method
8387      * can enforce the semantic that requesting a check on a null global
8388      * permission is automatically denied.  (Internally a null permission
8389      * string is used when calling {@link #checkComponentPermission} in cases
8390      * when only uid-based security is needed.)
8391      *
8392      * This can be called with or without the global lock held.
8393      */
8394     @Override
8395     public int checkPermission(String permission, int pid, int uid) {
8396         if (permission == null) {
8397             return PackageManager.PERMISSION_DENIED;
8398         }
8399         return checkComponentPermission(permission, pid, uid, -1, true);
8400     }
8401
8402     @Override
8403     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8404         if (permission == null) {
8405             return PackageManager.PERMISSION_DENIED;
8406         }
8407
8408         // We might be performing an operation on behalf of an indirect binder
8409         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8410         // client identity accordingly before proceeding.
8411         Identity tlsIdentity = sCallerIdentity.get();
8412         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8413             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8414                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8415             uid = tlsIdentity.uid;
8416             pid = tlsIdentity.pid;
8417         }
8418
8419         return checkComponentPermission(permission, pid, uid, -1, true);
8420     }
8421
8422     /**
8423      * Binder IPC calls go through the public entry point.
8424      * This can be called with or without the global lock held.
8425      */
8426     int checkCallingPermission(String permission) {
8427         return checkPermission(permission,
8428                 Binder.getCallingPid(),
8429                 UserHandle.getAppId(Binder.getCallingUid()));
8430     }
8431
8432     /**
8433      * This can be called with or without the global lock held.
8434      */
8435     void enforceCallingPermission(String permission, String func) {
8436         if (checkCallingPermission(permission)
8437                 == PackageManager.PERMISSION_GRANTED) {
8438             return;
8439         }
8440
8441         String msg = "Permission Denial: " + func + " from pid="
8442                 + Binder.getCallingPid()
8443                 + ", uid=" + Binder.getCallingUid()
8444                 + " requires " + permission;
8445         Slog.w(TAG, msg);
8446         throw new SecurityException(msg);
8447     }
8448
8449     /**
8450      * Determine if UID is holding permissions required to access {@link Uri} in
8451      * the given {@link ProviderInfo}. Final permission checking is always done
8452      * in {@link ContentProvider}.
8453      */
8454     private final boolean checkHoldingPermissionsLocked(
8455             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8456         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8457                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8458         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8459             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8460                     != PERMISSION_GRANTED) {
8461                 return false;
8462             }
8463         }
8464         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8465     }
8466
8467     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8468             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8469         if (pi.applicationInfo.uid == uid) {
8470             return true;
8471         } else if (!pi.exported) {
8472             return false;
8473         }
8474
8475         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8476         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8477         try {
8478             // check if target holds top-level <provider> permissions
8479             if (!readMet && pi.readPermission != null && considerUidPermissions
8480                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8481                 readMet = true;
8482             }
8483             if (!writeMet && pi.writePermission != null && considerUidPermissions
8484                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8485                 writeMet = true;
8486             }
8487
8488             // track if unprotected read/write is allowed; any denied
8489             // <path-permission> below removes this ability
8490             boolean allowDefaultRead = pi.readPermission == null;
8491             boolean allowDefaultWrite = pi.writePermission == null;
8492
8493             // check if target holds any <path-permission> that match uri
8494             final PathPermission[] pps = pi.pathPermissions;
8495             if (pps != null) {
8496                 final String path = grantUri.uri.getPath();
8497                 int i = pps.length;
8498                 while (i > 0 && (!readMet || !writeMet)) {
8499                     i--;
8500                     PathPermission pp = pps[i];
8501                     if (pp.match(path)) {
8502                         if (!readMet) {
8503                             final String pprperm = pp.getReadPermission();
8504                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8505                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8506                                     + ": match=" + pp.match(path)
8507                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8508                             if (pprperm != null) {
8509                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8510                                         == PERMISSION_GRANTED) {
8511                                     readMet = true;
8512                                 } else {
8513                                     allowDefaultRead = false;
8514                                 }
8515                             }
8516                         }
8517                         if (!writeMet) {
8518                             final String ppwperm = pp.getWritePermission();
8519                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8520                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8521                                     + ": match=" + pp.match(path)
8522                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8523                             if (ppwperm != null) {
8524                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8525                                         == PERMISSION_GRANTED) {
8526                                     writeMet = true;
8527                                 } else {
8528                                     allowDefaultWrite = false;
8529                                 }
8530                             }
8531                         }
8532                     }
8533                 }
8534             }
8535
8536             // grant unprotected <provider> read/write, if not blocked by
8537             // <path-permission> above
8538             if (allowDefaultRead) readMet = true;
8539             if (allowDefaultWrite) writeMet = true;
8540
8541         } catch (RemoteException e) {
8542             return false;
8543         }
8544
8545         return readMet && writeMet;
8546     }
8547
8548     public boolean isAppStartModeDisabled(int uid, String packageName) {
8549         synchronized (this) {
8550             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8551                     == ActivityManager.APP_START_MODE_DISABLED;
8552         }
8553     }
8554
8555     // Unified app-op and target sdk check
8556     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8557         // Apps that target O+ are always subject to background check
8558         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8559             if (DEBUG_BACKGROUND_CHECK) {
8560                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8561             }
8562             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8563         }
8564         // ...and legacy apps get an AppOp check
8565         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8566                 uid, packageName);
8567         if (DEBUG_BACKGROUND_CHECK) {
8568             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8569         }
8570         switch (appop) {
8571             case AppOpsManager.MODE_ALLOWED:
8572                 return ActivityManager.APP_START_MODE_NORMAL;
8573             case AppOpsManager.MODE_IGNORED:
8574                 return ActivityManager.APP_START_MODE_DELAYED;
8575             default:
8576                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8577         }
8578     }
8579
8580     // Service launch is available to apps with run-in-background exemptions but
8581     // some other background operations are not.  If we're doing a check
8582     // of service-launch policy, allow those callers to proceed unrestricted.
8583     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8584         // Persistent app?
8585         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8586             if (DEBUG_BACKGROUND_CHECK) {
8587                 Slog.i(TAG, "App " + uid + "/" + packageName
8588                         + " is persistent; not restricted in background");
8589             }
8590             return ActivityManager.APP_START_MODE_NORMAL;
8591         }
8592
8593         // Non-persistent but background whitelisted?
8594         if (uidOnBackgroundWhitelist(uid)) {
8595             if (DEBUG_BACKGROUND_CHECK) {
8596                 Slog.i(TAG, "App " + uid + "/" + packageName
8597                         + " on background whitelist; not restricted in background");
8598             }
8599             return ActivityManager.APP_START_MODE_NORMAL;
8600         }
8601
8602         // Is this app on the battery whitelist?
8603         if (isOnDeviceIdleWhitelistLocked(uid)) {
8604             if (DEBUG_BACKGROUND_CHECK) {
8605                 Slog.i(TAG, "App " + uid + "/" + packageName
8606                         + " on idle whitelist; not restricted in background");
8607             }
8608             return ActivityManager.APP_START_MODE_NORMAL;
8609         }
8610
8611         // None of the service-policy criteria apply, so we apply the common criteria
8612         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8613     }
8614
8615     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8616             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8617         UidRecord uidRec = mActiveUids.get(uid);
8618         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8619                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8620                 + (uidRec != null ? uidRec.idle : false));
8621         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8622             boolean ephemeral;
8623             if (uidRec == null) {
8624                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8625                         UserHandle.getUserId(uid), packageName);
8626             } else {
8627                 ephemeral = uidRec.ephemeral;
8628             }
8629
8630             if (ephemeral) {
8631                 // We are hard-core about ephemeral apps not running in the background.
8632                 return ActivityManager.APP_START_MODE_DISABLED;
8633             } else {
8634                 if (disabledOnly) {
8635                     // The caller is only interested in whether app starts are completely
8636                     // disabled for the given package (that is, it is an instant app).  So
8637                     // we don't need to go further, which is all just seeing if we should
8638                     // apply a "delayed" mode for a regular app.
8639                     return ActivityManager.APP_START_MODE_NORMAL;
8640                 }
8641                 final int startMode = (alwaysRestrict)
8642                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8643                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8644                                 packageTargetSdk);
8645                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8646                         + " pkg=" + packageName + " startMode=" + startMode
8647                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8648                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8649                     // This is an old app that has been forced into a "compatible as possible"
8650                     // mode of background check.  To increase compatibility, we will allow other
8651                     // foreground apps to cause its services to start.
8652                     if (callingPid >= 0) {
8653                         ProcessRecord proc;
8654                         synchronized (mPidsSelfLocked) {
8655                             proc = mPidsSelfLocked.get(callingPid);
8656                         }
8657                         if (proc != null &&
8658                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8659                             // Whoever is instigating this is in the foreground, so we will allow it
8660                             // to go through.
8661                             return ActivityManager.APP_START_MODE_NORMAL;
8662                         }
8663                     }
8664                 }
8665                 return startMode;
8666             }
8667         }
8668         return ActivityManager.APP_START_MODE_NORMAL;
8669     }
8670
8671     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8672         final int appId = UserHandle.getAppId(uid);
8673         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8674                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8675                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8676     }
8677
8678     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8679         ProviderInfo pi = null;
8680         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8681         if (cpr != null) {
8682             pi = cpr.info;
8683         } else {
8684             try {
8685                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8686                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8687                         userHandle);
8688             } catch (RemoteException ex) {
8689             }
8690         }
8691         return pi;
8692     }
8693
8694     void grantEphemeralAccessLocked(int userId, Intent intent,
8695             int targetAppId, int ephemeralAppId) {
8696         getPackageManagerInternalLocked().
8697                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8698     }
8699
8700     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8701         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8702         if (targetUris != null) {
8703             return targetUris.get(grantUri);
8704         }
8705         return null;
8706     }
8707
8708     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8709             String targetPkg, int targetUid, GrantUri grantUri) {
8710         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8711         if (targetUris == null) {
8712             targetUris = Maps.newArrayMap();
8713             mGrantedUriPermissions.put(targetUid, targetUris);
8714         }
8715
8716         UriPermission perm = targetUris.get(grantUri);
8717         if (perm == null) {
8718             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8719             targetUris.put(grantUri, perm);
8720         }
8721
8722         return perm;
8723     }
8724
8725     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8726             final int modeFlags) {
8727         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8728         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8729                 : UriPermission.STRENGTH_OWNED;
8730
8731         // Root gets to do everything.
8732         if (uid == 0) {
8733             return true;
8734         }
8735
8736         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8737         if (perms == null) return false;
8738
8739         // First look for exact match
8740         final UriPermission exactPerm = perms.get(grantUri);
8741         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8742             return true;
8743         }
8744
8745         // No exact match, look for prefixes
8746         final int N = perms.size();
8747         for (int i = 0; i < N; i++) {
8748             final UriPermission perm = perms.valueAt(i);
8749             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8750                     && perm.getStrength(modeFlags) >= minStrength) {
8751                 return true;
8752             }
8753         }
8754
8755         return false;
8756     }
8757
8758     /**
8759      * @param uri This uri must NOT contain an embedded userId.
8760      * @param userId The userId in which the uri is to be resolved.
8761      */
8762     @Override
8763     public int checkUriPermission(Uri uri, int pid, int uid,
8764             final int modeFlags, int userId, IBinder callerToken) {
8765         enforceNotIsolatedCaller("checkUriPermission");
8766
8767         // Another redirected-binder-call permissions check as in
8768         // {@link checkPermissionWithToken}.
8769         Identity tlsIdentity = sCallerIdentity.get();
8770         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8771             uid = tlsIdentity.uid;
8772             pid = tlsIdentity.pid;
8773         }
8774
8775         // Our own process gets to do everything.
8776         if (pid == MY_PID) {
8777             return PackageManager.PERMISSION_GRANTED;
8778         }
8779         synchronized (this) {
8780             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8781                     ? PackageManager.PERMISSION_GRANTED
8782                     : PackageManager.PERMISSION_DENIED;
8783         }
8784     }
8785
8786     /**
8787      * Check if the targetPkg can be granted permission to access uri by
8788      * the callingUid using the given modeFlags.  Throws a security exception
8789      * if callingUid is not allowed to do this.  Returns the uid of the target
8790      * if the URI permission grant should be performed; returns -1 if it is not
8791      * needed (for example targetPkg already has permission to access the URI).
8792      * If you already know the uid of the target, you can supply it in
8793      * lastTargetUid else set that to -1.
8794      */
8795     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8796             final int modeFlags, int lastTargetUid) {
8797         if (!Intent.isAccessUriMode(modeFlags)) {
8798             return -1;
8799         }
8800
8801         if (targetPkg != null) {
8802             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8803                     "Checking grant " + targetPkg + " permission to " + grantUri);
8804         }
8805
8806         final IPackageManager pm = AppGlobals.getPackageManager();
8807
8808         // If this is not a content: uri, we can't do anything with it.
8809         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8810             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8811                     "Can't grant URI permission for non-content URI: " + grantUri);
8812             return -1;
8813         }
8814
8815         // Bail early if system is trying to hand out permissions directly; it
8816         // must always grant permissions on behalf of someone explicit.
8817         final int callingAppId = UserHandle.getAppId(callingUid);
8818         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8819             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8820                 // Exempted authority for cropping user photos in Settings app
8821             } else {
8822                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8823                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8824                 return -1;
8825             }
8826         }
8827
8828         final String authority = grantUri.uri.getAuthority();
8829         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8830                 MATCH_DEBUG_TRIAGED_MISSING);
8831         if (pi == null) {
8832             Slog.w(TAG, "No content provider found for permission check: " +
8833                     grantUri.uri.toSafeString());
8834             return -1;
8835         }
8836
8837         int targetUid = lastTargetUid;
8838         if (targetUid < 0 && targetPkg != null) {
8839             try {
8840                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8841                         UserHandle.getUserId(callingUid));
8842                 if (targetUid < 0) {
8843                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844                             "Can't grant URI permission no uid for: " + targetPkg);
8845                     return -1;
8846                 }
8847             } catch (RemoteException ex) {
8848                 return -1;
8849             }
8850         }
8851
8852         // If we're extending a persistable grant, then we always need to create
8853         // the grant data structure so that take/release APIs work
8854         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8855             return targetUid;
8856         }
8857
8858         if (targetUid >= 0) {
8859             // First...  does the target actually need this permission?
8860             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8861                 // No need to grant the target this permission.
8862                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8863                         "Target " + targetPkg + " already has full permission to " + grantUri);
8864                 return -1;
8865             }
8866         } else {
8867             // First...  there is no target package, so can anyone access it?
8868             boolean allowed = pi.exported;
8869             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8870                 if (pi.readPermission != null) {
8871                     allowed = false;
8872                 }
8873             }
8874             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8875                 if (pi.writePermission != null) {
8876                     allowed = false;
8877                 }
8878             }
8879             if (allowed) {
8880                 return -1;
8881             }
8882         }
8883
8884         /* There is a special cross user grant if:
8885          * - The target is on another user.
8886          * - Apps on the current user can access the uri without any uid permissions.
8887          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8888          * grant uri permissions.
8889          */
8890         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8891                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8892                 modeFlags, false /*without considering the uid permissions*/);
8893
8894         // Second...  is the provider allowing granting of URI permissions?
8895         if (!specialCrossUserGrant) {
8896             if (!pi.grantUriPermissions) {
8897                 throw new SecurityException("Provider " + pi.packageName
8898                         + "/" + pi.name
8899                         + " does not allow granting of Uri permissions (uri "
8900                         + grantUri + ")");
8901             }
8902             if (pi.uriPermissionPatterns != null) {
8903                 final int N = pi.uriPermissionPatterns.length;
8904                 boolean allowed = false;
8905                 for (int i=0; i<N; i++) {
8906                     if (pi.uriPermissionPatterns[i] != null
8907                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8908                         allowed = true;
8909                         break;
8910                     }
8911                 }
8912                 if (!allowed) {
8913                     throw new SecurityException("Provider " + pi.packageName
8914                             + "/" + pi.name
8915                             + " does not allow granting of permission to path of Uri "
8916                             + grantUri);
8917                 }
8918             }
8919         }
8920
8921         // Third...  does the caller itself have permission to access
8922         // this uri?
8923         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8924             // Require they hold a strong enough Uri permission
8925             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8926                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8927                     throw new SecurityException(
8928                             "UID " + callingUid + " does not have permission to " + grantUri
8929                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8930                                     + "or related APIs");
8931                 } else {
8932                     throw new SecurityException(
8933                             "UID " + callingUid + " does not have permission to " + grantUri);
8934                 }
8935             }
8936         }
8937         return targetUid;
8938     }
8939
8940     /**
8941      * @param uri This uri must NOT contain an embedded userId.
8942      * @param userId The userId in which the uri is to be resolved.
8943      */
8944     @Override
8945     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8946             final int modeFlags, int userId) {
8947         enforceNotIsolatedCaller("checkGrantUriPermission");
8948         synchronized(this) {
8949             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8950                     new GrantUri(userId, uri, false), modeFlags, -1);
8951         }
8952     }
8953
8954     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8955             final int modeFlags, UriPermissionOwner owner) {
8956         if (!Intent.isAccessUriMode(modeFlags)) {
8957             return;
8958         }
8959
8960         // So here we are: the caller has the assumed permission
8961         // to the uri, and the target doesn't.  Let's now give this to
8962         // the target.
8963
8964         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8965                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8966
8967         final String authority = grantUri.uri.getAuthority();
8968         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8969                 MATCH_DEBUG_TRIAGED_MISSING);
8970         if (pi == null) {
8971             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8972             return;
8973         }
8974
8975         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8976             grantUri.prefix = true;
8977         }
8978         final UriPermission perm = findOrCreateUriPermissionLocked(
8979                 pi.packageName, targetPkg, targetUid, grantUri);
8980         perm.grantModes(modeFlags, owner);
8981     }
8982
8983     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8984             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8985         if (targetPkg == null) {
8986             throw new NullPointerException("targetPkg");
8987         }
8988         int targetUid;
8989         final IPackageManager pm = AppGlobals.getPackageManager();
8990         try {
8991             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8992         } catch (RemoteException ex) {
8993             return;
8994         }
8995
8996         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8997                 targetUid);
8998         if (targetUid < 0) {
8999             return;
9000         }
9001
9002         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9003                 owner);
9004     }
9005
9006     static class NeededUriGrants extends ArrayList<GrantUri> {
9007         final String targetPkg;
9008         final int targetUid;
9009         final int flags;
9010
9011         NeededUriGrants(String targetPkg, int targetUid, int flags) {
9012             this.targetPkg = targetPkg;
9013             this.targetUid = targetUid;
9014             this.flags = flags;
9015         }
9016     }
9017
9018     /**
9019      * Like checkGrantUriPermissionLocked, but takes an Intent.
9020      */
9021     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9022             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9023         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9024                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9025                 + " clip=" + (intent != null ? intent.getClipData() : null)
9026                 + " from " + intent + "; flags=0x"
9027                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9028
9029         if (targetPkg == null) {
9030             throw new NullPointerException("targetPkg");
9031         }
9032
9033         if (intent == null) {
9034             return null;
9035         }
9036         Uri data = intent.getData();
9037         ClipData clip = intent.getClipData();
9038         if (data == null && clip == null) {
9039             return null;
9040         }
9041         // Default userId for uris in the intent (if they don't specify it themselves)
9042         int contentUserHint = intent.getContentUserHint();
9043         if (contentUserHint == UserHandle.USER_CURRENT) {
9044             contentUserHint = UserHandle.getUserId(callingUid);
9045         }
9046         final IPackageManager pm = AppGlobals.getPackageManager();
9047         int targetUid;
9048         if (needed != null) {
9049             targetUid = needed.targetUid;
9050         } else {
9051             try {
9052                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9053                         targetUserId);
9054             } catch (RemoteException ex) {
9055                 return null;
9056             }
9057             if (targetUid < 0) {
9058                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9059                         "Can't grant URI permission no uid for: " + targetPkg
9060                         + " on user " + targetUserId);
9061                 return null;
9062             }
9063         }
9064         if (data != null) {
9065             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9066             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9067                     targetUid);
9068             if (targetUid > 0) {
9069                 if (needed == null) {
9070                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9071                 }
9072                 needed.add(grantUri);
9073             }
9074         }
9075         if (clip != null) {
9076             for (int i=0; i<clip.getItemCount(); i++) {
9077                 Uri uri = clip.getItemAt(i).getUri();
9078                 if (uri != null) {
9079                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9080                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9081                             targetUid);
9082                     if (targetUid > 0) {
9083                         if (needed == null) {
9084                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9085                         }
9086                         needed.add(grantUri);
9087                     }
9088                 } else {
9089                     Intent clipIntent = clip.getItemAt(i).getIntent();
9090                     if (clipIntent != null) {
9091                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9092                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9093                         if (newNeeded != null) {
9094                             needed = newNeeded;
9095                         }
9096                     }
9097                 }
9098             }
9099         }
9100
9101         return needed;
9102     }
9103
9104     /**
9105      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9106      */
9107     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9108             UriPermissionOwner owner) {
9109         if (needed != null) {
9110             for (int i=0; i<needed.size(); i++) {
9111                 GrantUri grantUri = needed.get(i);
9112                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9113                         grantUri, needed.flags, owner);
9114             }
9115         }
9116     }
9117
9118     void grantUriPermissionFromIntentLocked(int callingUid,
9119             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9120         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9121                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9122         if (needed == null) {
9123             return;
9124         }
9125
9126         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9127     }
9128
9129     /**
9130      * @param uri This uri must NOT contain an embedded userId.
9131      * @param userId The userId in which the uri is to be resolved.
9132      */
9133     @Override
9134     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9135             final int modeFlags, int userId) {
9136         enforceNotIsolatedCaller("grantUriPermission");
9137         GrantUri grantUri = new GrantUri(userId, uri, false);
9138         synchronized(this) {
9139             final ProcessRecord r = getRecordForAppLocked(caller);
9140             if (r == null) {
9141                 throw new SecurityException("Unable to find app for caller "
9142                         + caller
9143                         + " when granting permission to uri " + grantUri);
9144             }
9145             if (targetPkg == null) {
9146                 throw new IllegalArgumentException("null target");
9147             }
9148             if (grantUri == null) {
9149                 throw new IllegalArgumentException("null uri");
9150             }
9151
9152             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9153                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9154                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9155                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9156
9157             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9158                     UserHandle.getUserId(r.uid));
9159         }
9160     }
9161
9162     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9163         if (perm.modeFlags == 0) {
9164             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9165                     perm.targetUid);
9166             if (perms != null) {
9167                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9168                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9169
9170                 perms.remove(perm.uri);
9171                 if (perms.isEmpty()) {
9172                     mGrantedUriPermissions.remove(perm.targetUid);
9173                 }
9174             }
9175         }
9176     }
9177
9178     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9179             final int modeFlags) {
9180         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9181                 "Revoking all granted permissions to " + grantUri);
9182
9183         final IPackageManager pm = AppGlobals.getPackageManager();
9184         final String authority = grantUri.uri.getAuthority();
9185         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9186                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9187         if (pi == null) {
9188             Slog.w(TAG, "No content provider found for permission revoke: "
9189                     + grantUri.toSafeString());
9190             return;
9191         }
9192
9193         // Does the caller have this permission on the URI?
9194         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9195             // If they don't have direct access to the URI, then revoke any
9196             // ownerless URI permissions that have been granted to them.
9197             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9198             if (perms != null) {
9199                 boolean persistChanged = false;
9200                 for (int i = perms.size()-1; i >= 0; i--) {
9201                     final UriPermission perm = perms.valueAt(i);
9202                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9203                         continue;
9204                     }
9205                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9206                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9207                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9208                                 "Revoking non-owned " + perm.targetUid
9209                                 + " permission to " + perm.uri);
9210                         persistChanged |= perm.revokeModes(
9211                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9212                         if (perm.modeFlags == 0) {
9213                             perms.removeAt(i);
9214                         }
9215                     }
9216                 }
9217                 if (perms.isEmpty()) {
9218                     mGrantedUriPermissions.remove(callingUid);
9219                 }
9220                 if (persistChanged) {
9221                     schedulePersistUriGrants();
9222                 }
9223             }
9224             return;
9225         }
9226
9227         boolean persistChanged = false;
9228
9229         // Go through all of the permissions and remove any that match.
9230         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9231             final int targetUid = mGrantedUriPermissions.keyAt(i);
9232             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9233
9234             for (int j = perms.size()-1; j >= 0; j--) {
9235                 final UriPermission perm = perms.valueAt(j);
9236                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9237                     continue;
9238                 }
9239                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9240                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9241                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9242                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9243                     persistChanged |= perm.revokeModes(
9244                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9245                             targetPackage == null);
9246                     if (perm.modeFlags == 0) {
9247                         perms.removeAt(j);
9248                     }
9249                 }
9250             }
9251
9252             if (perms.isEmpty()) {
9253                 mGrantedUriPermissions.removeAt(i);
9254             }
9255         }
9256
9257         if (persistChanged) {
9258             schedulePersistUriGrants();
9259         }
9260     }
9261
9262     /**
9263      * @param uri This uri must NOT contain an embedded userId.
9264      * @param userId The userId in which the uri is to be resolved.
9265      */
9266     @Override
9267     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9268             final int modeFlags, int userId) {
9269         enforceNotIsolatedCaller("revokeUriPermission");
9270         synchronized(this) {
9271             final ProcessRecord r = getRecordForAppLocked(caller);
9272             if (r == null) {
9273                 throw new SecurityException("Unable to find app for caller "
9274                         + caller
9275                         + " when revoking permission to uri " + uri);
9276             }
9277             if (uri == null) {
9278                 Slog.w(TAG, "revokeUriPermission: null uri");
9279                 return;
9280             }
9281
9282             if (!Intent.isAccessUriMode(modeFlags)) {
9283                 return;
9284             }
9285
9286             final String authority = uri.getAuthority();
9287             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9288                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9289             if (pi == null) {
9290                 Slog.w(TAG, "No content provider found for permission revoke: "
9291                         + uri.toSafeString());
9292                 return;
9293             }
9294
9295             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9296                     modeFlags);
9297         }
9298     }
9299
9300     /**
9301      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9302      * given package.
9303      *
9304      * @param packageName Package name to match, or {@code null} to apply to all
9305      *            packages.
9306      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9307      *            to all users.
9308      * @param persistable If persistable grants should be removed.
9309      */
9310     private void removeUriPermissionsForPackageLocked(
9311             String packageName, int userHandle, boolean persistable) {
9312         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9313             throw new IllegalArgumentException("Must narrow by either package or user");
9314         }
9315
9316         boolean persistChanged = false;
9317
9318         int N = mGrantedUriPermissions.size();
9319         for (int i = 0; i < N; i++) {
9320             final int targetUid = mGrantedUriPermissions.keyAt(i);
9321             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9322
9323             // Only inspect grants matching user
9324             if (userHandle == UserHandle.USER_ALL
9325                     || userHandle == UserHandle.getUserId(targetUid)) {
9326                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9327                     final UriPermission perm = it.next();
9328
9329                     // Only inspect grants matching package
9330                     if (packageName == null || perm.sourcePkg.equals(packageName)
9331                             || perm.targetPkg.equals(packageName)) {
9332                         // Hacky solution as part of fixing a security bug; ignore
9333                         // grants associated with DownloadManager so we don't have
9334                         // to immediately launch it to regrant the permissions
9335                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9336                                 && !persistable) continue;
9337
9338                         persistChanged |= perm.revokeModes(persistable
9339                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9340
9341                         // Only remove when no modes remain; any persisted grants
9342                         // will keep this alive.
9343                         if (perm.modeFlags == 0) {
9344                             it.remove();
9345                         }
9346                     }
9347                 }
9348
9349                 if (perms.isEmpty()) {
9350                     mGrantedUriPermissions.remove(targetUid);
9351                     N--;
9352                     i--;
9353                 }
9354             }
9355         }
9356
9357         if (persistChanged) {
9358             schedulePersistUriGrants();
9359         }
9360     }
9361
9362     @Override
9363     public IBinder newUriPermissionOwner(String name) {
9364         enforceNotIsolatedCaller("newUriPermissionOwner");
9365         synchronized(this) {
9366             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9367             return owner.getExternalTokenLocked();
9368         }
9369     }
9370
9371     @Override
9372     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9373         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9374         synchronized(this) {
9375             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9376             if (r == null) {
9377                 throw new IllegalArgumentException("Activity does not exist; token="
9378                         + activityToken);
9379             }
9380             return r.getUriPermissionsLocked().getExternalTokenLocked();
9381         }
9382     }
9383     /**
9384      * @param uri This uri must NOT contain an embedded userId.
9385      * @param sourceUserId The userId in which the uri is to be resolved.
9386      * @param targetUserId The userId of the app that receives the grant.
9387      */
9388     @Override
9389     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9390             final int modeFlags, int sourceUserId, int targetUserId) {
9391         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9392                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9393                 "grantUriPermissionFromOwner", null);
9394         synchronized(this) {
9395             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9396             if (owner == null) {
9397                 throw new IllegalArgumentException("Unknown owner: " + token);
9398             }
9399             if (fromUid != Binder.getCallingUid()) {
9400                 if (Binder.getCallingUid() != myUid()) {
9401                     // Only system code can grant URI permissions on behalf
9402                     // of other users.
9403                     throw new SecurityException("nice try");
9404                 }
9405             }
9406             if (targetPkg == null) {
9407                 throw new IllegalArgumentException("null target");
9408             }
9409             if (uri == null) {
9410                 throw new IllegalArgumentException("null uri");
9411             }
9412
9413             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9414                     modeFlags, owner, targetUserId);
9415         }
9416     }
9417
9418     /**
9419      * @param uri This uri must NOT contain an embedded userId.
9420      * @param userId The userId in which the uri is to be resolved.
9421      */
9422     @Override
9423     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9424         synchronized(this) {
9425             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9426             if (owner == null) {
9427                 throw new IllegalArgumentException("Unknown owner: " + token);
9428             }
9429
9430             if (uri == null) {
9431                 owner.removeUriPermissionsLocked(mode);
9432             } else {
9433                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9434                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9435             }
9436         }
9437     }
9438
9439     private void schedulePersistUriGrants() {
9440         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9441             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9442                     10 * DateUtils.SECOND_IN_MILLIS);
9443         }
9444     }
9445
9446     private void writeGrantedUriPermissions() {
9447         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9448
9449         // Snapshot permissions so we can persist without lock
9450         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9451         synchronized (this) {
9452             final int size = mGrantedUriPermissions.size();
9453             for (int i = 0; i < size; i++) {
9454                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9455                 for (UriPermission perm : perms.values()) {
9456                     if (perm.persistedModeFlags != 0) {
9457                         persist.add(perm.snapshot());
9458                     }
9459                 }
9460             }
9461         }
9462
9463         FileOutputStream fos = null;
9464         try {
9465             fos = mGrantFile.startWrite();
9466
9467             XmlSerializer out = new FastXmlSerializer();
9468             out.setOutput(fos, StandardCharsets.UTF_8.name());
9469             out.startDocument(null, true);
9470             out.startTag(null, TAG_URI_GRANTS);
9471             for (UriPermission.Snapshot perm : persist) {
9472                 out.startTag(null, TAG_URI_GRANT);
9473                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9474                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9475                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9476                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9477                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9478                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9479                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9480                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9481                 out.endTag(null, TAG_URI_GRANT);
9482             }
9483             out.endTag(null, TAG_URI_GRANTS);
9484             out.endDocument();
9485
9486             mGrantFile.finishWrite(fos);
9487         } catch (IOException e) {
9488             if (fos != null) {
9489                 mGrantFile.failWrite(fos);
9490             }
9491         }
9492     }
9493
9494     private void readGrantedUriPermissionsLocked() {
9495         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9496
9497         final long now = System.currentTimeMillis();
9498
9499         FileInputStream fis = null;
9500         try {
9501             fis = mGrantFile.openRead();
9502             final XmlPullParser in = Xml.newPullParser();
9503             in.setInput(fis, StandardCharsets.UTF_8.name());
9504
9505             int type;
9506             while ((type = in.next()) != END_DOCUMENT) {
9507                 final String tag = in.getName();
9508                 if (type == START_TAG) {
9509                     if (TAG_URI_GRANT.equals(tag)) {
9510                         final int sourceUserId;
9511                         final int targetUserId;
9512                         final int userHandle = readIntAttribute(in,
9513                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9514                         if (userHandle != UserHandle.USER_NULL) {
9515                             // For backwards compatibility.
9516                             sourceUserId = userHandle;
9517                             targetUserId = userHandle;
9518                         } else {
9519                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9520                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9521                         }
9522                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9523                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9524                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9525                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9526                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9527                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9528
9529                         // Sanity check that provider still belongs to source package
9530                         // Both direct boot aware and unaware packages are fine as we
9531                         // will do filtering at query time to avoid multiple parsing.
9532                         final ProviderInfo pi = getProviderInfoLocked(
9533                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9534                                         | MATCH_DIRECT_BOOT_UNAWARE);
9535                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9536                             int targetUid = -1;
9537                             try {
9538                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9539                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9540                             } catch (RemoteException e) {
9541                             }
9542                             if (targetUid != -1) {
9543                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9544                                         sourcePkg, targetPkg, targetUid,
9545                                         new GrantUri(sourceUserId, uri, prefix));
9546                                 perm.initPersistedModes(modeFlags, createdTime);
9547                             }
9548                         } else {
9549                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9550                                     + " but instead found " + pi);
9551                         }
9552                     }
9553                 }
9554             }
9555         } catch (FileNotFoundException e) {
9556             // Missing grants is okay
9557         } catch (IOException e) {
9558             Slog.wtf(TAG, "Failed reading Uri grants", e);
9559         } catch (XmlPullParserException e) {
9560             Slog.wtf(TAG, "Failed reading Uri grants", e);
9561         } finally {
9562             IoUtils.closeQuietly(fis);
9563         }
9564     }
9565
9566     /**
9567      * @param uri This uri must NOT contain an embedded userId.
9568      * @param userId The userId in which the uri is to be resolved.
9569      */
9570     @Override
9571     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9572         enforceNotIsolatedCaller("takePersistableUriPermission");
9573
9574         Preconditions.checkFlagsArgument(modeFlags,
9575                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9576
9577         synchronized (this) {
9578             final int callingUid = Binder.getCallingUid();
9579             boolean persistChanged = false;
9580             GrantUri grantUri = new GrantUri(userId, uri, false);
9581
9582             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9583                     new GrantUri(userId, uri, false));
9584             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9585                     new GrantUri(userId, uri, true));
9586
9587             final boolean exactValid = (exactPerm != null)
9588                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9589             final boolean prefixValid = (prefixPerm != null)
9590                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9591
9592             if (!(exactValid || prefixValid)) {
9593                 throw new SecurityException("No persistable permission grants found for UID "
9594                         + callingUid + " and Uri " + grantUri.toSafeString());
9595             }
9596
9597             if (exactValid) {
9598                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9599             }
9600             if (prefixValid) {
9601                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9602             }
9603
9604             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9605
9606             if (persistChanged) {
9607                 schedulePersistUriGrants();
9608             }
9609         }
9610     }
9611
9612     /**
9613      * @param uri This uri must NOT contain an embedded userId.
9614      * @param userId The userId in which the uri is to be resolved.
9615      */
9616     @Override
9617     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9618         enforceNotIsolatedCaller("releasePersistableUriPermission");
9619
9620         Preconditions.checkFlagsArgument(modeFlags,
9621                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9622
9623         synchronized (this) {
9624             final int callingUid = Binder.getCallingUid();
9625             boolean persistChanged = false;
9626
9627             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9628                     new GrantUri(userId, uri, false));
9629             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9630                     new GrantUri(userId, uri, true));
9631             if (exactPerm == null && prefixPerm == null) {
9632                 throw new SecurityException("No permission grants found for UID " + callingUid
9633                         + " and Uri " + uri.toSafeString());
9634             }
9635
9636             if (exactPerm != null) {
9637                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9638                 removeUriPermissionIfNeededLocked(exactPerm);
9639             }
9640             if (prefixPerm != null) {
9641                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9642                 removeUriPermissionIfNeededLocked(prefixPerm);
9643             }
9644
9645             if (persistChanged) {
9646                 schedulePersistUriGrants();
9647             }
9648         }
9649     }
9650
9651     /**
9652      * Prune any older {@link UriPermission} for the given UID until outstanding
9653      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9654      *
9655      * @return if any mutations occured that require persisting.
9656      */
9657     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9658         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9659         if (perms == null) return false;
9660         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9661
9662         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9663         for (UriPermission perm : perms.values()) {
9664             if (perm.persistedModeFlags != 0) {
9665                 persisted.add(perm);
9666             }
9667         }
9668
9669         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9670         if (trimCount <= 0) return false;
9671
9672         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9673         for (int i = 0; i < trimCount; i++) {
9674             final UriPermission perm = persisted.get(i);
9675
9676             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9677                     "Trimming grant created at " + perm.persistedCreateTime);
9678
9679             perm.releasePersistableModes(~0);
9680             removeUriPermissionIfNeededLocked(perm);
9681         }
9682
9683         return true;
9684     }
9685
9686     @Override
9687     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9688             String packageName, boolean incoming) {
9689         enforceNotIsolatedCaller("getPersistedUriPermissions");
9690         Preconditions.checkNotNull(packageName, "packageName");
9691
9692         final int callingUid = Binder.getCallingUid();
9693         final int callingUserId = UserHandle.getUserId(callingUid);
9694         final IPackageManager pm = AppGlobals.getPackageManager();
9695         try {
9696             final int packageUid = pm.getPackageUid(packageName,
9697                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9698             if (packageUid != callingUid) {
9699                 throw new SecurityException(
9700                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9701             }
9702         } catch (RemoteException e) {
9703             throw new SecurityException("Failed to verify package name ownership");
9704         }
9705
9706         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9707         synchronized (this) {
9708             if (incoming) {
9709                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9710                         callingUid);
9711                 if (perms == null) {
9712                     Slog.w(TAG, "No permission grants found for " + packageName);
9713                 } else {
9714                     for (UriPermission perm : perms.values()) {
9715                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9716                             result.add(perm.buildPersistedPublicApiObject());
9717                         }
9718                     }
9719                 }
9720             } else {
9721                 final int size = mGrantedUriPermissions.size();
9722                 for (int i = 0; i < size; i++) {
9723                     final ArrayMap<GrantUri, UriPermission> perms =
9724                             mGrantedUriPermissions.valueAt(i);
9725                     for (UriPermission perm : perms.values()) {
9726                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9727                             result.add(perm.buildPersistedPublicApiObject());
9728                         }
9729                     }
9730                 }
9731             }
9732         }
9733         return new ParceledListSlice<android.content.UriPermission>(result);
9734     }
9735
9736     @Override
9737     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9738             String packageName, int userId) {
9739         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9740                 "getGrantedUriPermissions");
9741
9742         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9743         synchronized (this) {
9744             final int size = mGrantedUriPermissions.size();
9745             for (int i = 0; i < size; i++) {
9746                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9747                 for (UriPermission perm : perms.values()) {
9748                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9749                             && perm.persistedModeFlags != 0) {
9750                         result.add(perm.buildPersistedPublicApiObject());
9751                     }
9752                 }
9753             }
9754         }
9755         return new ParceledListSlice<android.content.UriPermission>(result);
9756     }
9757
9758     @Override
9759     public void clearGrantedUriPermissions(String packageName, int userId) {
9760         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9761                 "clearGrantedUriPermissions");
9762         removeUriPermissionsForPackageLocked(packageName, userId, true);
9763     }
9764
9765     @Override
9766     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9767         synchronized (this) {
9768             ProcessRecord app =
9769                 who != null ? getRecordForAppLocked(who) : null;
9770             if (app == null) return;
9771
9772             Message msg = Message.obtain();
9773             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9774             msg.obj = app;
9775             msg.arg1 = waiting ? 1 : 0;
9776             mUiHandler.sendMessage(msg);
9777         }
9778     }
9779
9780     @Override
9781     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9782         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9783         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9784         outInfo.availMem = getFreeMemory();
9785         outInfo.totalMem = getTotalMemory();
9786         outInfo.threshold = homeAppMem;
9787         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9788         outInfo.hiddenAppThreshold = cachedAppMem;
9789         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9790                 ProcessList.SERVICE_ADJ);
9791         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9792                 ProcessList.VISIBLE_APP_ADJ);
9793         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9794                 ProcessList.FOREGROUND_APP_ADJ);
9795     }
9796
9797     // =========================================================
9798     // TASK MANAGEMENT
9799     // =========================================================
9800
9801     @Override
9802     public List<IBinder> getAppTasks(String callingPackage) {
9803         int callingUid = Binder.getCallingUid();
9804         long ident = Binder.clearCallingIdentity();
9805
9806         synchronized(this) {
9807             ArrayList<IBinder> list = new ArrayList<IBinder>();
9808             try {
9809                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9810
9811                 final int N = mRecentTasks.size();
9812                 for (int i = 0; i < N; i++) {
9813                     TaskRecord tr = mRecentTasks.get(i);
9814                     // Skip tasks that do not match the caller.  We don't need to verify
9815                     // callingPackage, because we are also limiting to callingUid and know
9816                     // that will limit to the correct security sandbox.
9817                     if (tr.effectiveUid != callingUid) {
9818                         continue;
9819                     }
9820                     Intent intent = tr.getBaseIntent();
9821                     if (intent == null ||
9822                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9823                         continue;
9824                     }
9825                     ActivityManager.RecentTaskInfo taskInfo =
9826                             createRecentTaskInfoFromTaskRecord(tr);
9827                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9828                     list.add(taskImpl.asBinder());
9829                 }
9830             } finally {
9831                 Binder.restoreCallingIdentity(ident);
9832             }
9833             return list;
9834         }
9835     }
9836
9837     @Override
9838     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9839         final int callingUid = Binder.getCallingUid();
9840         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9841
9842         synchronized(this) {
9843             if (DEBUG_ALL) Slog.v(
9844                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9845
9846             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9847                     callingUid);
9848
9849             // TODO: Improve with MRU list from all ActivityStacks.
9850             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9851         }
9852
9853         return list;
9854     }
9855
9856     /**
9857      * Creates a new RecentTaskInfo from a TaskRecord.
9858      */
9859     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9860         // Update the task description to reflect any changes in the task stack
9861         tr.updateTaskDescription();
9862
9863         // Compose the recent task info
9864         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9865         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9866         rti.persistentId = tr.taskId;
9867         rti.baseIntent = new Intent(tr.getBaseIntent());
9868         rti.origActivity = tr.origActivity;
9869         rti.realActivity = tr.realActivity;
9870         rti.description = tr.lastDescription;
9871         rti.stackId = tr.getStackId();
9872         rti.userId = tr.userId;
9873         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9874         rti.firstActiveTime = tr.firstActiveTime;
9875         rti.lastActiveTime = tr.lastActiveTime;
9876         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9877         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9878         rti.numActivities = 0;
9879         if (tr.mBounds != null) {
9880             rti.bounds = new Rect(tr.mBounds);
9881         }
9882         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9883         rti.resizeMode = tr.mResizeMode;
9884
9885         ActivityRecord base = null;
9886         ActivityRecord top = null;
9887         ActivityRecord tmp;
9888
9889         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9890             tmp = tr.mActivities.get(i);
9891             if (tmp.finishing) {
9892                 continue;
9893             }
9894             base = tmp;
9895             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9896                 top = base;
9897             }
9898             rti.numActivities++;
9899         }
9900
9901         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9902         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9903
9904         return rti;
9905     }
9906
9907     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9908         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9909                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9910         if (!allowed) {
9911             if (checkPermission(android.Manifest.permission.GET_TASKS,
9912                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9913                 // Temporary compatibility: some existing apps on the system image may
9914                 // still be requesting the old permission and not switched to the new
9915                 // one; if so, we'll still allow them full access.  This means we need
9916                 // to see if they are holding the old permission and are a system app.
9917                 try {
9918                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9919                         allowed = true;
9920                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9921                                 + " is using old GET_TASKS but privileged; allowing");
9922                     }
9923                 } catch (RemoteException e) {
9924                 }
9925             }
9926         }
9927         if (!allowed) {
9928             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9929                     + " does not hold REAL_GET_TASKS; limiting output");
9930         }
9931         return allowed;
9932     }
9933
9934     @Override
9935     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9936             int userId) {
9937         final int callingUid = Binder.getCallingUid();
9938         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9939                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9940
9941         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9942         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9943         synchronized (this) {
9944             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9945                     callingUid);
9946             final boolean detailed = checkCallingPermission(
9947                     android.Manifest.permission.GET_DETAILED_TASKS)
9948                     == PackageManager.PERMISSION_GRANTED;
9949
9950             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9951                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9952                 return ParceledListSlice.emptyList();
9953             }
9954             mRecentTasks.loadUserRecentsLocked(userId);
9955
9956             final int recentsCount = mRecentTasks.size();
9957             ArrayList<ActivityManager.RecentTaskInfo> res =
9958                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9959
9960             final Set<Integer> includedUsers;
9961             if (includeProfiles) {
9962                 includedUsers = mUserController.getProfileIds(userId);
9963             } else {
9964                 includedUsers = new HashSet<>();
9965             }
9966             includedUsers.add(Integer.valueOf(userId));
9967
9968             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9969                 TaskRecord tr = mRecentTasks.get(i);
9970                 // Only add calling user or related users recent tasks
9971                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9972                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9973                     continue;
9974                 }
9975
9976                 if (tr.realActivitySuspended) {
9977                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9978                     continue;
9979                 }
9980
9981                 // Return the entry if desired by the caller.  We always return
9982                 // the first entry, because callers always expect this to be the
9983                 // foreground app.  We may filter others if the caller has
9984                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9985                 // we should exclude the entry.
9986
9987                 if (i == 0
9988                         || withExcluded
9989                         || (tr.intent == null)
9990                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9991                                 == 0)) {
9992                     if (!allowed) {
9993                         // If the caller doesn't have the GET_TASKS permission, then only
9994                         // allow them to see a small subset of tasks -- their own and home.
9995                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9996                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9997                             continue;
9998                         }
9999                     }
10000                     final ActivityStack stack = tr.getStack();
10001                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10002                         if (stack != null && stack.isHomeOrRecentsStack()) {
10003                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10004                                     "Skipping, home or recents stack task: " + tr);
10005                             continue;
10006                         }
10007                     }
10008                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10009                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10010                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10011                                     "Skipping, top task in docked stack: " + tr);
10012                             continue;
10013                         }
10014                     }
10015                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10016                         if (stack != null && stack.isPinnedStack()) {
10017                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10018                                     "Skipping, pinned stack task: " + tr);
10019                             continue;
10020                         }
10021                     }
10022                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10023                         // Don't include auto remove tasks that are finished or finishing.
10024                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025                                 "Skipping, auto-remove without activity: " + tr);
10026                         continue;
10027                     }
10028                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10029                             && !tr.isAvailable) {
10030                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10031                                 "Skipping, unavail real act: " + tr);
10032                         continue;
10033                     }
10034
10035                     if (!tr.mUserSetupComplete) {
10036                         // Don't include task launched while user is not done setting-up.
10037                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10038                                 "Skipping, user setup not complete: " + tr);
10039                         continue;
10040                     }
10041
10042                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10043                     if (!detailed) {
10044                         rti.baseIntent.replaceExtras((Bundle)null);
10045                     }
10046
10047                     res.add(rti);
10048                     maxNum--;
10049                 }
10050             }
10051             return new ParceledListSlice<>(res);
10052         }
10053     }
10054
10055     @Override
10056     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10057         synchronized (this) {
10058             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10059                     "getTaskThumbnail()");
10060             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10061                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10062             if (tr != null) {
10063                 return tr.getTaskThumbnailLocked();
10064             }
10065         }
10066         return null;
10067     }
10068
10069     @Override
10070     public ActivityManager.TaskDescription getTaskDescription(int id) {
10071         synchronized (this) {
10072             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10073                     "getTaskDescription()");
10074             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10075                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10076             if (tr != null) {
10077                 return tr.lastTaskDescription;
10078             }
10079         }
10080         return null;
10081     }
10082
10083     @Override
10084     public int addAppTask(IBinder activityToken, Intent intent,
10085             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10086         final int callingUid = Binder.getCallingUid();
10087         final long callingIdent = Binder.clearCallingIdentity();
10088
10089         try {
10090             synchronized (this) {
10091                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10092                 if (r == null) {
10093                     throw new IllegalArgumentException("Activity does not exist; token="
10094                             + activityToken);
10095                 }
10096                 ComponentName comp = intent.getComponent();
10097                 if (comp == null) {
10098                     throw new IllegalArgumentException("Intent " + intent
10099                             + " must specify explicit component");
10100                 }
10101                 if (thumbnail.getWidth() != mThumbnailWidth
10102                         || thumbnail.getHeight() != mThumbnailHeight) {
10103                     throw new IllegalArgumentException("Bad thumbnail size: got "
10104                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10105                             + mThumbnailWidth + "x" + mThumbnailHeight);
10106                 }
10107                 if (intent.getSelector() != null) {
10108                     intent.setSelector(null);
10109                 }
10110                 if (intent.getSourceBounds() != null) {
10111                     intent.setSourceBounds(null);
10112                 }
10113                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10114                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10115                         // The caller has added this as an auto-remove task...  that makes no
10116                         // sense, so turn off auto-remove.
10117                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10118                     }
10119                 }
10120                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10121                     mLastAddedTaskActivity = null;
10122                 }
10123                 ActivityInfo ainfo = mLastAddedTaskActivity;
10124                 if (ainfo == null) {
10125                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10126                             comp, 0, UserHandle.getUserId(callingUid));
10127                     if (ainfo.applicationInfo.uid != callingUid) {
10128                         throw new SecurityException(
10129                                 "Can't add task for another application: target uid="
10130                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10131                     }
10132                 }
10133
10134                 TaskRecord task = new TaskRecord(this,
10135                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10136                         ainfo, intent, description, new TaskThumbnailInfo());
10137
10138                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10139                 if (trimIdx >= 0) {
10140                     // If this would have caused a trim, then we'll abort because that
10141                     // means it would be added at the end of the list but then just removed.
10142                     return INVALID_TASK_ID;
10143                 }
10144
10145                 final int N = mRecentTasks.size();
10146                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10147                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10148                     tr.removedFromRecents();
10149                 }
10150
10151                 task.inRecents = true;
10152                 mRecentTasks.add(task);
10153                 r.getStack().addTask(task, false, "addAppTask");
10154
10155                 task.setLastThumbnailLocked(thumbnail);
10156                 task.freeLastThumbnail();
10157                 return task.taskId;
10158             }
10159         } finally {
10160             Binder.restoreCallingIdentity(callingIdent);
10161         }
10162     }
10163
10164     @Override
10165     public Point getAppTaskThumbnailSize() {
10166         synchronized (this) {
10167             return new Point(mThumbnailWidth,  mThumbnailHeight);
10168         }
10169     }
10170
10171     @Override
10172     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10173         synchronized (this) {
10174             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10175             if (r != null) {
10176                 r.setTaskDescription(td);
10177                 final TaskRecord task = r.getTask();
10178                 task.updateTaskDescription();
10179                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10180             }
10181         }
10182     }
10183
10184     @Override
10185     public void setTaskResizeable(int taskId, int resizeableMode) {
10186         synchronized (this) {
10187             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10188                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10189             if (task == null) {
10190                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10191                 return;
10192             }
10193             task.setResizeMode(resizeableMode);
10194         }
10195     }
10196
10197     @Override
10198     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10199         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10200         long ident = Binder.clearCallingIdentity();
10201         try {
10202             synchronized (this) {
10203                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10204                 if (task == null) {
10205                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10206                     return;
10207                 }
10208                 // Place the task in the right stack if it isn't there already based on
10209                 // the requested bounds.
10210                 // The stack transition logic is:
10211                 // - a null bounds on a freeform task moves that task to fullscreen
10212                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10213                 //   that task to freeform
10214                 // - otherwise the task is not moved
10215                 int stackId = task.getStackId();
10216                 if (!StackId.isTaskResizeAllowed(stackId)) {
10217                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10218                 }
10219                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10220                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10221                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10222                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10223                 }
10224
10225                 // Reparent the task to the right stack if necessary
10226                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10227                 if (stackId != task.getStackId()) {
10228                     // Defer resume until the task is resized below
10229                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10230                             DEFER_RESUME, "resizeTask");
10231                     preserveWindow = false;
10232                 }
10233
10234                 // After reparenting (which only resizes the task to the stack bounds), resize the
10235                 // task to the actual bounds provided
10236                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10237             }
10238         } finally {
10239             Binder.restoreCallingIdentity(ident);
10240         }
10241     }
10242
10243     @Override
10244     public Rect getTaskBounds(int taskId) {
10245         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10246         long ident = Binder.clearCallingIdentity();
10247         Rect rect = new Rect();
10248         try {
10249             synchronized (this) {
10250                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10251                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10252                 if (task == null) {
10253                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10254                     return rect;
10255                 }
10256                 if (task.getStack() != null) {
10257                     // Return the bounds from window manager since it will be adjusted for various
10258                     // things like the presense of a docked stack for tasks that aren't resizeable.
10259                     task.getWindowContainerBounds(rect);
10260                 } else {
10261                     // Task isn't in window manager yet since it isn't associated with a stack.
10262                     // Return the persist value from activity manager
10263                     if (task.mBounds != null) {
10264                         rect.set(task.mBounds);
10265                     } else if (task.mLastNonFullscreenBounds != null) {
10266                         rect.set(task.mLastNonFullscreenBounds);
10267                     }
10268                 }
10269             }
10270         } finally {
10271             Binder.restoreCallingIdentity(ident);
10272         }
10273         return rect;
10274     }
10275
10276     @Override
10277     public void cancelTaskWindowTransition(int taskId) {
10278         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10279         final long ident = Binder.clearCallingIdentity();
10280         try {
10281             synchronized (this) {
10282                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10283                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10284                 if (task == null) {
10285                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10286                     return;
10287                 }
10288                 task.cancelWindowTransition();
10289             }
10290         } finally {
10291             Binder.restoreCallingIdentity(ident);
10292         }
10293     }
10294
10295     @Override
10296     public void cancelTaskThumbnailTransition(int taskId) {
10297         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10298         final long ident = Binder.clearCallingIdentity();
10299         try {
10300             synchronized (this) {
10301                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10302                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10303                 if (task == null) {
10304                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10305                     return;
10306                 }
10307                 task.cancelThumbnailTransition();
10308             }
10309         } finally {
10310             Binder.restoreCallingIdentity(ident);
10311         }
10312     }
10313
10314     @Override
10315     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10316         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10317         final long ident = Binder.clearCallingIdentity();
10318         try {
10319             final TaskRecord task;
10320             synchronized (this) {
10321                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10322                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10323                 if (task == null) {
10324                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10325                     return null;
10326                 }
10327             }
10328             // Don't call this while holding the lock as this operation might hit the disk.
10329             return task.getSnapshot(reducedResolution);
10330         } finally {
10331             Binder.restoreCallingIdentity(ident);
10332         }
10333     }
10334
10335     @Override
10336     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10337         if (userId != UserHandle.getCallingUserId()) {
10338             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10339                     "getTaskDescriptionIcon");
10340         }
10341         final File passedIconFile = new File(filePath);
10342         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10343                 passedIconFile.getName());
10344         if (!legitIconFile.getPath().equals(filePath)
10345                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10346             throw new IllegalArgumentException("Bad file path: " + filePath
10347                     + " passed for userId " + userId);
10348         }
10349         return mRecentTasks.getTaskDescriptionIcon(filePath);
10350     }
10351
10352     @Override
10353     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10354             throws RemoteException {
10355         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10356         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10357                 activityOptions.getCustomInPlaceResId() == 0) {
10358             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10359                     "with valid animation");
10360         }
10361         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10362         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10363                 activityOptions.getCustomInPlaceResId());
10364         mWindowManager.executeAppTransition();
10365     }
10366
10367     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10368         // Remove all tasks with activities in the specified package from the list of recent tasks
10369         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10370             TaskRecord tr = mRecentTasks.get(i);
10371             if (tr.userId != userId) continue;
10372
10373             ComponentName cn = tr.intent.getComponent();
10374             if (cn != null && cn.getPackageName().equals(packageName)) {
10375                 // If the package name matches, remove the task.
10376                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10377             }
10378         }
10379     }
10380
10381     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10382             int userId) {
10383
10384         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10385             TaskRecord tr = mRecentTasks.get(i);
10386             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10387                 continue;
10388             }
10389
10390             ComponentName cn = tr.intent.getComponent();
10391             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10392                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10393             if (sameComponent) {
10394                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10395             }
10396         }
10397     }
10398
10399     @Override
10400     public void removeStack(int stackId) {
10401         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10402         if (StackId.isHomeOrRecentsStack(stackId)) {
10403             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10404         }
10405
10406         synchronized (this) {
10407             final long ident = Binder.clearCallingIdentity();
10408             try {
10409                 mStackSupervisor.removeStackLocked(stackId);
10410             } finally {
10411                 Binder.restoreCallingIdentity(ident);
10412             }
10413         }
10414     }
10415
10416     @Override
10417     public void moveStackToDisplay(int stackId, int displayId) {
10418         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10419
10420         synchronized (this) {
10421             final long ident = Binder.clearCallingIdentity();
10422             try {
10423                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10424                         + " to displayId=" + displayId);
10425                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10426             } finally {
10427                 Binder.restoreCallingIdentity(ident);
10428             }
10429         }
10430     }
10431
10432     @Override
10433     public boolean removeTask(int taskId) {
10434         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10435         synchronized (this) {
10436             final long ident = Binder.clearCallingIdentity();
10437             try {
10438                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10439             } finally {
10440                 Binder.restoreCallingIdentity(ident);
10441             }
10442         }
10443     }
10444
10445     /**
10446      * TODO: Add mController hook
10447      */
10448     @Override
10449     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10450         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10451
10452         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10453         synchronized(this) {
10454             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10455         }
10456     }
10457
10458     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10459         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10460
10461         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10462                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10463             ActivityOptions.abort(options);
10464             return;
10465         }
10466         final long origId = Binder.clearCallingIdentity();
10467         try {
10468             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10469             if (task == null) {
10470                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10471                 return;
10472             }
10473             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10474                 mStackSupervisor.showLockTaskToast();
10475                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10476                 return;
10477             }
10478             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10479             if (prev != null) {
10480                 task.setTaskToReturnTo(prev);
10481             }
10482             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10483                     false /* forceNonResizable */);
10484
10485             final ActivityRecord topActivity = task.getTopActivity();
10486             if (topActivity != null) {
10487
10488                 // We are reshowing a task, use a starting window to hide the initial draw delay
10489                 // so the transition can start earlier.
10490                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10491                         true /* taskSwitch */, fromRecents);
10492             }
10493         } finally {
10494             Binder.restoreCallingIdentity(origId);
10495         }
10496         ActivityOptions.abort(options);
10497     }
10498
10499     /**
10500      * Attempts to move a task backwards in z-order (the order of activities within the task is
10501      * unchanged).
10502      *
10503      * There are several possible results of this call:
10504      * - if the task is locked, then we will show the lock toast
10505      * - if there is a task behind the provided task, then that task is made visible and resumed as
10506      *   this task is moved to the back
10507      * - otherwise, if there are no other tasks in the stack:
10508      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10509      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10510      *       (depending on whether it is visible)
10511      *     - otherwise, we simply return home and hide this task
10512      *
10513      * @param token A reference to the activity we wish to move
10514      * @param nonRoot If false then this only works if the activity is the root
10515      *                of a task; if true it will work for any activity in a task.
10516      * @return Returns true if the move completed, false if not.
10517      */
10518     @Override
10519     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10520         enforceNotIsolatedCaller("moveActivityTaskToBack");
10521         synchronized(this) {
10522             final long origId = Binder.clearCallingIdentity();
10523             try {
10524                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10525                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10526                 if (task != null) {
10527                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10528                 }
10529             } finally {
10530                 Binder.restoreCallingIdentity(origId);
10531             }
10532         }
10533         return false;
10534     }
10535
10536     @Override
10537     public void moveTaskBackwards(int task) {
10538         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10539                 "moveTaskBackwards()");
10540
10541         synchronized(this) {
10542             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10543                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10544                 return;
10545             }
10546             final long origId = Binder.clearCallingIdentity();
10547             moveTaskBackwardsLocked(task);
10548             Binder.restoreCallingIdentity(origId);
10549         }
10550     }
10551
10552     private final void moveTaskBackwardsLocked(int task) {
10553         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10554     }
10555
10556     @Override
10557     public int createStackOnDisplay(int displayId) throws RemoteException {
10558         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10559         synchronized (this) {
10560             final int stackId = mStackSupervisor.getNextStackId();
10561             final ActivityStack stack =
10562                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10563             if (stack == null) {
10564                 return INVALID_STACK_ID;
10565             }
10566             return stack.mStackId;
10567         }
10568     }
10569
10570     @Override
10571     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10572         synchronized (this) {
10573             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10574             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10575                 return stack.mDisplayId;
10576             }
10577             return DEFAULT_DISPLAY;
10578         }
10579     }
10580
10581     @Override
10582     public int getActivityStackId(IBinder token) throws RemoteException {
10583         synchronized (this) {
10584             ActivityStack stack = ActivityRecord.getStackLocked(token);
10585             if (stack == null) {
10586                 return INVALID_STACK_ID;
10587             }
10588             return stack.mStackId;
10589         }
10590     }
10591
10592     @Override
10593     public void exitFreeformMode(IBinder token) throws RemoteException {
10594         synchronized (this) {
10595             long ident = Binder.clearCallingIdentity();
10596             try {
10597                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10598                 if (r == null) {
10599                     throw new IllegalArgumentException(
10600                             "exitFreeformMode: No activity record matching token=" + token);
10601                 }
10602
10603                 final ActivityStack stack = r.getStack();
10604                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10605                     throw new IllegalStateException(
10606                             "exitFreeformMode: You can only go fullscreen from freeform.");
10607                 }
10608
10609                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10610                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10611                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10612             } finally {
10613                 Binder.restoreCallingIdentity(ident);
10614             }
10615         }
10616     }
10617
10618     @Override
10619     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10620         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10621         if (StackId.isHomeOrRecentsStack(stackId)) {
10622             throw new IllegalArgumentException(
10623                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10624         }
10625         synchronized (this) {
10626             long ident = Binder.clearCallingIdentity();
10627             try {
10628                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10629                 if (task == null) {
10630                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10631                     return;
10632                 }
10633
10634                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10635                         + " to stackId=" + stackId + " toTop=" + toTop);
10636                 if (stackId == DOCKED_STACK_ID) {
10637                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10638                             null /* initialBounds */);
10639                 }
10640                 task.reparent(stackId, toTop,
10641                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10642             } finally {
10643                 Binder.restoreCallingIdentity(ident);
10644             }
10645         }
10646     }
10647
10648     @Override
10649     public void swapDockedAndFullscreenStack() throws RemoteException {
10650         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10651         synchronized (this) {
10652             long ident = Binder.clearCallingIdentity();
10653             try {
10654                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10655                         FULLSCREEN_WORKSPACE_STACK_ID);
10656                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10657                         : null;
10658                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10659                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10660                         : null;
10661                 if (topTask == null || tasks == null || tasks.size() == 0) {
10662                     Slog.w(TAG,
10663                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10664                     return;
10665                 }
10666
10667                 // TODO: App transition
10668                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10669
10670                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10671                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10672                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10673                 final int size = tasks.size();
10674                 for (int i = 0; i < size; i++) {
10675                     final int id = tasks.get(i).taskId;
10676                     if (id == topTask.taskId) {
10677                         continue;
10678                     }
10679
10680                     // Defer the resume until after all the tasks have been moved
10681                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10682                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10683                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10684                 }
10685
10686                 // Because we deferred the resume to avoid conflicts with stack switches while
10687                 // resuming, we need to do it after all the tasks are moved.
10688                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10689                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10690
10691                 mWindowManager.executeAppTransition();
10692             } finally {
10693                 Binder.restoreCallingIdentity(ident);
10694             }
10695         }
10696     }
10697
10698     /**
10699      * Moves the input task to the docked stack.
10700      *
10701      * @param taskId Id of task to move.
10702      * @param createMode The mode the docked stack should be created in if it doesn't exist
10703      *                   already. See
10704      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10705      *                   and
10706      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10707      * @param toTop If the task and stack should be moved to the top.
10708      * @param animate Whether we should play an animation for the moving the task
10709      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10710      *                      docked stack. Pass {@code null} to use default bounds.
10711      */
10712     @Override
10713     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10714             Rect initialBounds) {
10715         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10716         synchronized (this) {
10717             long ident = Binder.clearCallingIdentity();
10718             try {
10719                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10720                 if (task == null) {
10721                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10722                     return false;
10723                 }
10724
10725                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10726                         + " to createMode=" + createMode + " toTop=" + toTop);
10727                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10728
10729                 // Defer resuming until we move the home stack to the front below
10730                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10731                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10732                         "moveTaskToDockedStack");
10733                 if (moved) {
10734                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10735                 }
10736                 return moved;
10737             } finally {
10738                 Binder.restoreCallingIdentity(ident);
10739             }
10740         }
10741     }
10742
10743     /**
10744      * Moves the top activity in the input stackId to the pinned stack.
10745      *
10746      * @param stackId Id of stack to move the top activity to pinned stack.
10747      * @param bounds Bounds to use for pinned stack.
10748      *
10749      * @return True if the top activity of the input stack was successfully moved to the pinned
10750      *          stack.
10751      */
10752     @Override
10753     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10754         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10755         synchronized (this) {
10756             if (!mSupportsPictureInPicture) {
10757                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10758                         + "Device doesn't support picture-in-picture mode");
10759             }
10760
10761             long ident = Binder.clearCallingIdentity();
10762             try {
10763                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10764             } finally {
10765                 Binder.restoreCallingIdentity(ident);
10766             }
10767         }
10768     }
10769
10770     @Override
10771     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10772             boolean preserveWindows, boolean animate, int animationDuration) {
10773         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10774         long ident = Binder.clearCallingIdentity();
10775         try {
10776             synchronized (this) {
10777                 if (animate) {
10778                     if (stackId == PINNED_STACK_ID) {
10779                         final PinnedActivityStack pinnedStack =
10780                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10781                         if (pinnedStack != null) {
10782                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10783                                     destBounds, animationDuration, false /* fromFullscreen */);
10784                         }
10785                     } else {
10786                         throw new IllegalArgumentException("Stack: " + stackId
10787                                 + " doesn't support animated resize.");
10788                     }
10789                 } else {
10790                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10791                             null /* tempTaskInsetBounds */, preserveWindows,
10792                             allowResizeInDockedMode, !DEFER_RESUME);
10793                 }
10794             }
10795         } finally {
10796             Binder.restoreCallingIdentity(ident);
10797         }
10798     }
10799
10800     @Override
10801     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10802             Rect tempDockedTaskInsetBounds,
10803             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10804         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10805                 "resizeDockedStack()");
10806         long ident = Binder.clearCallingIdentity();
10807         try {
10808             synchronized (this) {
10809                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10810                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10811                         PRESERVE_WINDOWS);
10812             }
10813         } finally {
10814             Binder.restoreCallingIdentity(ident);
10815         }
10816     }
10817
10818     @Override
10819     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10820         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10821                 "resizePinnedStack()");
10822         final long ident = Binder.clearCallingIdentity();
10823         try {
10824             synchronized (this) {
10825                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10826             }
10827         } finally {
10828             Binder.restoreCallingIdentity(ident);
10829         }
10830     }
10831
10832     /**
10833      * Try to place task to provided position. The final position might be different depending on
10834      * current user and stacks state. The task will be moved to target stack if it's currently in
10835      * different stack.
10836      */
10837     @Override
10838     public void positionTaskInStack(int taskId, int stackId, int position) {
10839         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10840         if (StackId.isHomeOrRecentsStack(stackId)) {
10841             throw new IllegalArgumentException(
10842                     "positionTaskInStack: Attempt to change the position of task "
10843                     + taskId + " in/to home/recents stack");
10844         }
10845         synchronized (this) {
10846             long ident = Binder.clearCallingIdentity();
10847             try {
10848                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10849                         + taskId + " in stackId=" + stackId + " at position=" + position);
10850                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10851                 if (task == null) {
10852                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10853                             + taskId);
10854                 }
10855
10856                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10857                         !ON_TOP);
10858
10859                 // TODO: Have the callers of this API call a separate reparent method if that is
10860                 // what they intended to do vs. having this method also do reparenting.
10861                 if (task.getStack() == stack) {
10862                     // Change position in current stack.
10863                     stack.positionChildAt(task, position);
10864                 } else {
10865                     // Reparent to new stack.
10866                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10867                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10868                 }
10869             } finally {
10870                 Binder.restoreCallingIdentity(ident);
10871             }
10872         }
10873     }
10874
10875     @Override
10876     public List<StackInfo> getAllStackInfos() {
10877         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10878         long ident = Binder.clearCallingIdentity();
10879         try {
10880             synchronized (this) {
10881                 return mStackSupervisor.getAllStackInfosLocked();
10882             }
10883         } finally {
10884             Binder.restoreCallingIdentity(ident);
10885         }
10886     }
10887
10888     @Override
10889     public StackInfo getStackInfo(int stackId) {
10890         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10891         long ident = Binder.clearCallingIdentity();
10892         try {
10893             synchronized (this) {
10894                 return mStackSupervisor.getStackInfoLocked(stackId);
10895             }
10896         } finally {
10897             Binder.restoreCallingIdentity(ident);
10898         }
10899     }
10900
10901     @Override
10902     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10903         synchronized(this) {
10904             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10905         }
10906     }
10907
10908     @Override
10909     public void updateDeviceOwner(String packageName) {
10910         final int callingUid = Binder.getCallingUid();
10911         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10912             throw new SecurityException("updateDeviceOwner called from non-system process");
10913         }
10914         synchronized (this) {
10915             mDeviceOwnerName = packageName;
10916         }
10917     }
10918
10919     @Override
10920     public void updateLockTaskPackages(int userId, String[] packages) {
10921         final int callingUid = Binder.getCallingUid();
10922         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10923             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10924                     "updateLockTaskPackages()");
10925         }
10926         synchronized (this) {
10927             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10928                     Arrays.toString(packages));
10929             mLockTaskPackages.put(userId, packages);
10930             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10931         }
10932     }
10933
10934
10935     void startLockTaskModeLocked(TaskRecord task) {
10936         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10937         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10938             return;
10939         }
10940
10941         // When a task is locked, dismiss the pinned stack if it exists
10942         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10943                 PINNED_STACK_ID);
10944         if (pinnedStack != null) {
10945             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10946         }
10947
10948         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10949         // is initiated by system after the pinning request was shown and locked mode is initiated
10950         // by an authorized app directly
10951         final int callingUid = Binder.getCallingUid();
10952         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10953         long ident = Binder.clearCallingIdentity();
10954         try {
10955             if (!isSystemInitiated) {
10956                 task.mLockTaskUid = callingUid;
10957                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10958                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10959                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10960                     StatusBarManagerInternal statusBarManager =
10961                             LocalServices.getService(StatusBarManagerInternal.class);
10962                     if (statusBarManager != null) {
10963                         statusBarManager.showScreenPinningRequest(task.taskId);
10964                     }
10965                     return;
10966                 }
10967
10968                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10969                 if (stack == null || task != stack.topTask()) {
10970                     throw new IllegalArgumentException("Invalid task, not in foreground");
10971                 }
10972             }
10973             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10974                     "Locking fully");
10975             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10976                     ActivityManager.LOCK_TASK_MODE_PINNED :
10977                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10978                     "startLockTask", true);
10979         } finally {
10980             Binder.restoreCallingIdentity(ident);
10981         }
10982     }
10983
10984     @Override
10985     public void startLockTaskModeById(int taskId) {
10986         synchronized (this) {
10987             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10988             if (task != null) {
10989                 startLockTaskModeLocked(task);
10990             }
10991         }
10992     }
10993
10994     @Override
10995     public void startLockTaskModeByToken(IBinder token) {
10996         synchronized (this) {
10997             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10998             if (r == null) {
10999                 return;
11000             }
11001             final TaskRecord task = r.getTask();
11002             if (task != null) {
11003                 startLockTaskModeLocked(task);
11004             }
11005         }
11006     }
11007
11008     @Override
11009     public void startSystemLockTaskMode(int taskId) throws RemoteException {
11010         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11011         // This makes inner call to look as if it was initiated by system.
11012         long ident = Binder.clearCallingIdentity();
11013         try {
11014             synchronized (this) {
11015                 startLockTaskModeById(taskId);
11016             }
11017         } finally {
11018             Binder.restoreCallingIdentity(ident);
11019         }
11020     }
11021
11022     @Override
11023     public void stopLockTaskMode() {
11024         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11025         if (lockTask == null) {
11026             // Our work here is done.
11027             return;
11028         }
11029
11030         final int callingUid = Binder.getCallingUid();
11031         final int lockTaskUid = lockTask.mLockTaskUid;
11032         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11033         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11034             // Done.
11035             return;
11036         } else {
11037             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11038             // It is possible lockTaskMode was started by the system process because
11039             // android:lockTaskMode is set to a locking value in the application manifest
11040             // instead of the app calling startLockTaskMode. In this case
11041             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11042             // {@link TaskRecord.effectiveUid} instead. Also caller with
11043             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11044             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11045                     && callingUid != lockTaskUid
11046                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11047                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11048                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11049             }
11050         }
11051         long ident = Binder.clearCallingIdentity();
11052         try {
11053             Log.d(TAG, "stopLockTaskMode");
11054             // Stop lock task
11055             synchronized (this) {
11056                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11057                         "stopLockTask", true);
11058             }
11059             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11060             if (tm != null) {
11061                 tm.showInCallScreen(false);
11062             }
11063         } finally {
11064             Binder.restoreCallingIdentity(ident);
11065         }
11066     }
11067
11068     /**
11069      * This API should be called by SystemUI only when user perform certain action to dismiss
11070      * lock task mode. We should only dismiss pinned lock task mode in this case.
11071      */
11072     @Override
11073     public void stopSystemLockTaskMode() throws RemoteException {
11074         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11075             stopLockTaskMode();
11076         } else {
11077             mStackSupervisor.showLockTaskToast();
11078         }
11079     }
11080
11081     @Override
11082     public boolean isInLockTaskMode() {
11083         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11084     }
11085
11086     @Override
11087     public int getLockTaskModeState() {
11088         synchronized (this) {
11089             return mStackSupervisor.getLockTaskModeState();
11090         }
11091     }
11092
11093     @Override
11094     public void showLockTaskEscapeMessage(IBinder token) {
11095         synchronized (this) {
11096             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11097             if (r == null) {
11098                 return;
11099             }
11100             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11101         }
11102     }
11103
11104     @Override
11105     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11106             throws RemoteException {
11107         synchronized (this) {
11108             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11109             if (r == null) {
11110                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11111                         + token);
11112                 return;
11113             }
11114             final long origId = Binder.clearCallingIdentity();
11115             try {
11116                 r.setDisablePreviewScreenshots(disable);
11117             } finally {
11118                 Binder.restoreCallingIdentity(origId);
11119             }
11120         }
11121     }
11122
11123     // =========================================================
11124     // CONTENT PROVIDERS
11125     // =========================================================
11126
11127     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11128         List<ProviderInfo> providers = null;
11129         try {
11130             providers = AppGlobals.getPackageManager()
11131                     .queryContentProviders(app.processName, app.uid,
11132                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11133                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11134                     .getList();
11135         } catch (RemoteException ex) {
11136         }
11137         if (DEBUG_MU) Slog.v(TAG_MU,
11138                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11139         int userId = app.userId;
11140         if (providers != null) {
11141             int N = providers.size();
11142             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11143             for (int i=0; i<N; i++) {
11144                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11145                 ProviderInfo cpi =
11146                     (ProviderInfo)providers.get(i);
11147                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11148                         cpi.name, cpi.flags);
11149                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11150                     // This is a singleton provider, but a user besides the
11151                     // default user is asking to initialize a process it runs
11152                     // in...  well, no, it doesn't actually run in this process,
11153                     // it runs in the process of the default user.  Get rid of it.
11154                     providers.remove(i);
11155                     N--;
11156                     i--;
11157                     continue;
11158                 }
11159
11160                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11161                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11162                 if (cpr == null) {
11163                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11164                     mProviderMap.putProviderByClass(comp, cpr);
11165                 }
11166                 if (DEBUG_MU) Slog.v(TAG_MU,
11167                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11168                 app.pubProviders.put(cpi.name, cpr);
11169                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11170                     // Don't add this if it is a platform component that is marked
11171                     // to run in multiple processes, because this is actually
11172                     // part of the framework so doesn't make sense to track as a
11173                     // separate apk in the process.
11174                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11175                             mProcessStats);
11176                 }
11177                 notifyPackageUse(cpi.applicationInfo.packageName,
11178                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11179             }
11180         }
11181         return providers;
11182     }
11183
11184     /**
11185      * Check if the calling UID has a possible chance at accessing the provider
11186      * at the given authority and user.
11187      */
11188     public String checkContentProviderAccess(String authority, int userId) {
11189         if (userId == UserHandle.USER_ALL) {
11190             mContext.enforceCallingOrSelfPermission(
11191                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11192             userId = UserHandle.getCallingUserId();
11193         }
11194
11195         ProviderInfo cpi = null;
11196         try {
11197             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11198                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11199                             | PackageManager.MATCH_DISABLED_COMPONENTS
11200                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11201                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11202                     userId);
11203         } catch (RemoteException ignored) {
11204         }
11205         if (cpi == null) {
11206             return "Failed to find provider " + authority + " for user " + userId
11207                     + "; expected to find a valid ContentProvider for this authority";
11208         }
11209
11210         ProcessRecord r = null;
11211         synchronized (mPidsSelfLocked) {
11212             r = mPidsSelfLocked.get(Binder.getCallingPid());
11213         }
11214         if (r == null) {
11215             return "Failed to find PID " + Binder.getCallingPid();
11216         }
11217
11218         synchronized (this) {
11219             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11220         }
11221     }
11222
11223     /**
11224      * Check if {@link ProcessRecord} has a possible chance at accessing the
11225      * given {@link ProviderInfo}. Final permission checking is always done
11226      * in {@link ContentProvider}.
11227      */
11228     private final String checkContentProviderPermissionLocked(
11229             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11230         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11231         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11232         boolean checkedGrants = false;
11233         if (checkUser) {
11234             // Looking for cross-user grants before enforcing the typical cross-users permissions
11235             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11236             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11237                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11238                     return null;
11239                 }
11240                 checkedGrants = true;
11241             }
11242             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11243                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11244             if (userId != tmpTargetUserId) {
11245                 // When we actually went to determine the final targer user ID, this ended
11246                 // up different than our initial check for the authority.  This is because
11247                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11248                 // SELF.  So we need to re-check the grants again.
11249                 checkedGrants = false;
11250             }
11251         }
11252         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11253                 cpi.applicationInfo.uid, cpi.exported)
11254                 == PackageManager.PERMISSION_GRANTED) {
11255             return null;
11256         }
11257         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11258                 cpi.applicationInfo.uid, cpi.exported)
11259                 == PackageManager.PERMISSION_GRANTED) {
11260             return null;
11261         }
11262
11263         PathPermission[] pps = cpi.pathPermissions;
11264         if (pps != null) {
11265             int i = pps.length;
11266             while (i > 0) {
11267                 i--;
11268                 PathPermission pp = pps[i];
11269                 String pprperm = pp.getReadPermission();
11270                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11271                         cpi.applicationInfo.uid, cpi.exported)
11272                         == PackageManager.PERMISSION_GRANTED) {
11273                     return null;
11274                 }
11275                 String ppwperm = pp.getWritePermission();
11276                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11277                         cpi.applicationInfo.uid, cpi.exported)
11278                         == PackageManager.PERMISSION_GRANTED) {
11279                     return null;
11280                 }
11281             }
11282         }
11283         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11284             return null;
11285         }
11286
11287         final String suffix;
11288         if (!cpi.exported) {
11289             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11290         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11291             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11292         } else {
11293             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11294         }
11295         final String msg = "Permission Denial: opening provider " + cpi.name
11296                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11297                 + ", uid=" + callingUid + ")" + suffix;
11298         Slog.w(TAG, msg);
11299         return msg;
11300     }
11301
11302     /**
11303      * Returns if the ContentProvider has granted a uri to callingUid
11304      */
11305     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11306         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11307         if (perms != null) {
11308             for (int i=perms.size()-1; i>=0; i--) {
11309                 GrantUri grantUri = perms.keyAt(i);
11310                 if (grantUri.sourceUserId == userId || !checkUser) {
11311                     if (matchesProvider(grantUri.uri, cpi)) {
11312                         return true;
11313                     }
11314                 }
11315             }
11316         }
11317         return false;
11318     }
11319
11320     /**
11321      * Returns true if the uri authority is one of the authorities specified in the provider.
11322      */
11323     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11324         String uriAuth = uri.getAuthority();
11325         String cpiAuth = cpi.authority;
11326         if (cpiAuth.indexOf(';') == -1) {
11327             return cpiAuth.equals(uriAuth);
11328         }
11329         String[] cpiAuths = cpiAuth.split(";");
11330         int length = cpiAuths.length;
11331         for (int i = 0; i < length; i++) {
11332             if (cpiAuths[i].equals(uriAuth)) return true;
11333         }
11334         return false;
11335     }
11336
11337     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11338             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11339         if (r != null) {
11340             for (int i=0; i<r.conProviders.size(); i++) {
11341                 ContentProviderConnection conn = r.conProviders.get(i);
11342                 if (conn.provider == cpr) {
11343                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11344                             "Adding provider requested by "
11345                             + r.processName + " from process "
11346                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11347                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11348                     if (stable) {
11349                         conn.stableCount++;
11350                         conn.numStableIncs++;
11351                     } else {
11352                         conn.unstableCount++;
11353                         conn.numUnstableIncs++;
11354                     }
11355                     return conn;
11356                 }
11357             }
11358             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11359             if (stable) {
11360                 conn.stableCount = 1;
11361                 conn.numStableIncs = 1;
11362             } else {
11363                 conn.unstableCount = 1;
11364                 conn.numUnstableIncs = 1;
11365             }
11366             cpr.connections.add(conn);
11367             r.conProviders.add(conn);
11368             startAssociationLocked(r.uid, r.processName, r.curProcState,
11369                     cpr.uid, cpr.name, cpr.info.processName);
11370             return conn;
11371         }
11372         cpr.addExternalProcessHandleLocked(externalProcessToken);
11373         return null;
11374     }
11375
11376     boolean decProviderCountLocked(ContentProviderConnection conn,
11377             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11378         if (conn != null) {
11379             cpr = conn.provider;
11380             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11381                     "Removing provider requested by "
11382                     + conn.client.processName + " from process "
11383                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11384                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11385             if (stable) {
11386                 conn.stableCount--;
11387             } else {
11388                 conn.unstableCount--;
11389             }
11390             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11391                 cpr.connections.remove(conn);
11392                 conn.client.conProviders.remove(conn);
11393                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11394                     // The client is more important than last activity -- note the time this
11395                     // is happening, so we keep the old provider process around a bit as last
11396                     // activity to avoid thrashing it.
11397                     if (cpr.proc != null) {
11398                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11399                     }
11400                 }
11401                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11402                 return true;
11403             }
11404             return false;
11405         }
11406         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11407         return false;
11408     }
11409
11410     private void checkTime(long startTime, String where) {
11411         long now = SystemClock.uptimeMillis();
11412         if ((now-startTime) > 50) {
11413             // If we are taking more than 50ms, log about it.
11414             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11415         }
11416     }
11417
11418     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11419             PROC_SPACE_TERM,
11420             PROC_SPACE_TERM|PROC_PARENS,
11421             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11422     };
11423
11424     private final long[] mProcessStateStatsLongs = new long[1];
11425
11426     boolean isProcessAliveLocked(ProcessRecord proc) {
11427         if (proc.procStatFile == null) {
11428             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11429         }
11430         mProcessStateStatsLongs[0] = 0;
11431         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11432                 mProcessStateStatsLongs, null)) {
11433             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11434             return false;
11435         }
11436         final long state = mProcessStateStatsLongs[0];
11437         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11438                 + (char)state);
11439         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11440     }
11441
11442     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11443             String name, IBinder token, boolean stable, int userId) {
11444         ContentProviderRecord cpr;
11445         ContentProviderConnection conn = null;
11446         ProviderInfo cpi = null;
11447
11448         synchronized(this) {
11449             long startTime = SystemClock.uptimeMillis();
11450
11451             ProcessRecord r = null;
11452             if (caller != null) {
11453                 r = getRecordForAppLocked(caller);
11454                 if (r == null) {
11455                     throw new SecurityException(
11456                             "Unable to find app for caller " + caller
11457                           + " (pid=" + Binder.getCallingPid()
11458                           + ") when getting content provider " + name);
11459                 }
11460             }
11461
11462             boolean checkCrossUser = true;
11463
11464             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11465
11466             // First check if this content provider has been published...
11467             cpr = mProviderMap.getProviderByName(name, userId);
11468             // If that didn't work, check if it exists for user 0 and then
11469             // verify that it's a singleton provider before using it.
11470             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11471                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11472                 if (cpr != null) {
11473                     cpi = cpr.info;
11474                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11475                             cpi.name, cpi.flags)
11476                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11477                         userId = UserHandle.USER_SYSTEM;
11478                         checkCrossUser = false;
11479                     } else {
11480                         cpr = null;
11481                         cpi = null;
11482                     }
11483                 }
11484             }
11485
11486             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11487             if (providerRunning) {
11488                 cpi = cpr.info;
11489                 String msg;
11490                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11491                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11492                         != null) {
11493                     throw new SecurityException(msg);
11494                 }
11495                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11496
11497                 if (r != null && cpr.canRunHere(r)) {
11498                     // This provider has been published or is in the process
11499                     // of being published...  but it is also allowed to run
11500                     // in the caller's process, so don't make a connection
11501                     // and just let the caller instantiate its own instance.
11502                     ContentProviderHolder holder = cpr.newHolder(null);
11503                     // don't give caller the provider object, it needs
11504                     // to make its own.
11505                     holder.provider = null;
11506                     return holder;
11507                 }
11508                 // Don't expose providers between normal apps and instant apps
11509                 try {
11510                     if (AppGlobals.getPackageManager()
11511                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11512                         return null;
11513                     }
11514                 } catch (RemoteException e) {
11515                 }
11516
11517                 final long origId = Binder.clearCallingIdentity();
11518
11519                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11520
11521                 // In this case the provider instance already exists, so we can
11522                 // return it right away.
11523                 conn = incProviderCountLocked(r, cpr, token, stable);
11524                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11525                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11526                         // If this is a perceptible app accessing the provider,
11527                         // make sure to count it as being accessed and thus
11528                         // back up on the LRU list.  This is good because
11529                         // content providers are often expensive to start.
11530                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11531                         updateLruProcessLocked(cpr.proc, false, null);
11532                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11533                     }
11534                 }
11535
11536                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11537                 final int verifiedAdj = cpr.proc.verifiedAdj;
11538                 boolean success = updateOomAdjLocked(cpr.proc, true);
11539                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11540                 // if the process has been successfully adjusted.  So to reduce races with
11541                 // it, we will check whether the process still exists.  Note that this doesn't
11542                 // completely get rid of races with LMK killing the process, but should make
11543                 // them much smaller.
11544                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11545                     success = false;
11546                 }
11547                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11548                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11549                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11550                 // NOTE: there is still a race here where a signal could be
11551                 // pending on the process even though we managed to update its
11552                 // adj level.  Not sure what to do about this, but at least
11553                 // the race is now smaller.
11554                 if (!success) {
11555                     // Uh oh...  it looks like the provider's process
11556                     // has been killed on us.  We need to wait for a new
11557                     // process to be started, and make sure its death
11558                     // doesn't kill our process.
11559                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11560                             + " is crashing; detaching " + r);
11561                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11562                     checkTime(startTime, "getContentProviderImpl: before appDied");
11563                     appDiedLocked(cpr.proc);
11564                     checkTime(startTime, "getContentProviderImpl: after appDied");
11565                     if (!lastRef) {
11566                         // This wasn't the last ref our process had on
11567                         // the provider...  we have now been killed, bail.
11568                         return null;
11569                     }
11570                     providerRunning = false;
11571                     conn = null;
11572                 } else {
11573                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11574                 }
11575
11576                 Binder.restoreCallingIdentity(origId);
11577             }
11578
11579             if (!providerRunning) {
11580                 try {
11581                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11582                     cpi = AppGlobals.getPackageManager().
11583                         resolveContentProvider(name,
11584                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11585                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11586                 } catch (RemoteException ex) {
11587                 }
11588                 if (cpi == null) {
11589                     return null;
11590                 }
11591                 // If the provider is a singleton AND
11592                 // (it's a call within the same user || the provider is a
11593                 // privileged app)
11594                 // Then allow connecting to the singleton provider
11595                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11596                         cpi.name, cpi.flags)
11597                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11598                 if (singleton) {
11599                     userId = UserHandle.USER_SYSTEM;
11600                 }
11601                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11602                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11603
11604                 String msg;
11605                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11606                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11607                         != null) {
11608                     throw new SecurityException(msg);
11609                 }
11610                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11611
11612                 if (!mProcessesReady
11613                         && !cpi.processName.equals("system")) {
11614                     // If this content provider does not run in the system
11615                     // process, and the system is not yet ready to run other
11616                     // processes, then fail fast instead of hanging.
11617                     throw new IllegalArgumentException(
11618                             "Attempt to launch content provider before system ready");
11619                 }
11620
11621                 // Make sure that the user who owns this provider is running.  If not,
11622                 // we don't want to allow it to run.
11623                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11624                     Slog.w(TAG, "Unable to launch app "
11625                             + cpi.applicationInfo.packageName + "/"
11626                             + cpi.applicationInfo.uid + " for provider "
11627                             + name + ": user " + userId + " is stopped");
11628                     return null;
11629                 }
11630
11631                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11632                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11633                 cpr = mProviderMap.getProviderByClass(comp, userId);
11634                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11635                 final boolean firstClass = cpr == null;
11636                 if (firstClass) {
11637                     final long ident = Binder.clearCallingIdentity();
11638
11639                     // If permissions need a review before any of the app components can run,
11640                     // we return no provider and launch a review activity if the calling app
11641                     // is in the foreground.
11642                     if (mPermissionReviewRequired) {
11643                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11644                             return null;
11645                         }
11646                     }
11647
11648                     try {
11649                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11650                         ApplicationInfo ai =
11651                             AppGlobals.getPackageManager().
11652                                 getApplicationInfo(
11653                                         cpi.applicationInfo.packageName,
11654                                         STOCK_PM_FLAGS, userId);
11655                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11656                         if (ai == null) {
11657                             Slog.w(TAG, "No package info for content provider "
11658                                     + cpi.name);
11659                             return null;
11660                         }
11661                         ai = getAppInfoForUser(ai, userId);
11662                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11663                     } catch (RemoteException ex) {
11664                         // pm is in same process, this will never happen.
11665                     } finally {
11666                         Binder.restoreCallingIdentity(ident);
11667                     }
11668                 }
11669
11670                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11671
11672                 if (r != null && cpr.canRunHere(r)) {
11673                     // If this is a multiprocess provider, then just return its
11674                     // info and allow the caller to instantiate it.  Only do
11675                     // this if the provider is the same user as the caller's
11676                     // process, or can run as root (so can be in any process).
11677                     return cpr.newHolder(null);
11678                 }
11679
11680                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11681                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11682                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11683
11684                 // This is single process, and our app is now connecting to it.
11685                 // See if we are already in the process of launching this
11686                 // provider.
11687                 final int N = mLaunchingProviders.size();
11688                 int i;
11689                 for (i = 0; i < N; i++) {
11690                     if (mLaunchingProviders.get(i) == cpr) {
11691                         break;
11692                     }
11693                 }
11694
11695                 // If the provider is not already being launched, then get it
11696                 // started.
11697                 if (i >= N) {
11698                     final long origId = Binder.clearCallingIdentity();
11699
11700                     try {
11701                         // Content provider is now in use, its package can't be stopped.
11702                         try {
11703                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11704                             AppGlobals.getPackageManager().setPackageStoppedState(
11705                                     cpr.appInfo.packageName, false, userId);
11706                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11707                         } catch (RemoteException e) {
11708                         } catch (IllegalArgumentException e) {
11709                             Slog.w(TAG, "Failed trying to unstop package "
11710                                     + cpr.appInfo.packageName + ": " + e);
11711                         }
11712
11713                         // Use existing process if already started
11714                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11715                         ProcessRecord proc = getProcessRecordLocked(
11716                                 cpi.processName, cpr.appInfo.uid, false);
11717                         if (proc != null && proc.thread != null && !proc.killed) {
11718                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11719                                     "Installing in existing process " + proc);
11720                             if (!proc.pubProviders.containsKey(cpi.name)) {
11721                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11722                                 proc.pubProviders.put(cpi.name, cpr);
11723                                 try {
11724                                     proc.thread.scheduleInstallProvider(cpi);
11725                                 } catch (RemoteException e) {
11726                                 }
11727                             }
11728                         } else {
11729                             checkTime(startTime, "getContentProviderImpl: before start process");
11730                             proc = startProcessLocked(cpi.processName,
11731                                     cpr.appInfo, false, 0, "content provider",
11732                                     new ComponentName(cpi.applicationInfo.packageName,
11733                                             cpi.name), false, false, false);
11734                             checkTime(startTime, "getContentProviderImpl: after start process");
11735                             if (proc == null) {
11736                                 Slog.w(TAG, "Unable to launch app "
11737                                         + cpi.applicationInfo.packageName + "/"
11738                                         + cpi.applicationInfo.uid + " for provider "
11739                                         + name + ": process is bad");
11740                                 return null;
11741                             }
11742                         }
11743                         cpr.launchingApp = proc;
11744                         mLaunchingProviders.add(cpr);
11745                     } finally {
11746                         Binder.restoreCallingIdentity(origId);
11747                     }
11748                 }
11749
11750                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11751
11752                 // Make sure the provider is published (the same provider class
11753                 // may be published under multiple names).
11754                 if (firstClass) {
11755                     mProviderMap.putProviderByClass(comp, cpr);
11756                 }
11757
11758                 mProviderMap.putProviderByName(name, cpr);
11759                 conn = incProviderCountLocked(r, cpr, token, stable);
11760                 if (conn != null) {
11761                     conn.waiting = true;
11762                 }
11763             }
11764             checkTime(startTime, "getContentProviderImpl: done!");
11765
11766             grantEphemeralAccessLocked(userId, null /*intent*/,
11767                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11768         }
11769
11770         // Wait for the provider to be published...
11771         synchronized (cpr) {
11772             while (cpr.provider == null) {
11773                 if (cpr.launchingApp == null) {
11774                     Slog.w(TAG, "Unable to launch app "
11775                             + cpi.applicationInfo.packageName + "/"
11776                             + cpi.applicationInfo.uid + " for provider "
11777                             + name + ": launching app became null");
11778                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11779                             UserHandle.getUserId(cpi.applicationInfo.uid),
11780                             cpi.applicationInfo.packageName,
11781                             cpi.applicationInfo.uid, name);
11782                     return null;
11783                 }
11784                 try {
11785                     if (DEBUG_MU) Slog.v(TAG_MU,
11786                             "Waiting to start provider " + cpr
11787                             + " launchingApp=" + cpr.launchingApp);
11788                     if (conn != null) {
11789                         conn.waiting = true;
11790                     }
11791                     cpr.wait();
11792                 } catch (InterruptedException ex) {
11793                 } finally {
11794                     if (conn != null) {
11795                         conn.waiting = false;
11796                     }
11797                 }
11798             }
11799         }
11800         return cpr != null ? cpr.newHolder(conn) : null;
11801     }
11802
11803     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11804             ProcessRecord r, final int userId) {
11805         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11806                 cpi.packageName, userId)) {
11807
11808             final boolean callerForeground = r == null || r.setSchedGroup
11809                     != ProcessList.SCHED_GROUP_BACKGROUND;
11810
11811             // Show a permission review UI only for starting from a foreground app
11812             if (!callerForeground) {
11813                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11814                         + cpi.packageName + " requires a permissions review");
11815                 return false;
11816             }
11817
11818             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11819             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11820                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11821             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11822
11823             if (DEBUG_PERMISSIONS_REVIEW) {
11824                 Slog.i(TAG, "u" + userId + " Launching permission review "
11825                         + "for package " + cpi.packageName);
11826             }
11827
11828             final UserHandle userHandle = new UserHandle(userId);
11829             mHandler.post(new Runnable() {
11830                 @Override
11831                 public void run() {
11832                     mContext.startActivityAsUser(intent, userHandle);
11833                 }
11834             });
11835
11836             return false;
11837         }
11838
11839         return true;
11840     }
11841
11842     PackageManagerInternal getPackageManagerInternalLocked() {
11843         if (mPackageManagerInt == null) {
11844             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11845         }
11846         return mPackageManagerInt;
11847     }
11848
11849     @Override
11850     public final ContentProviderHolder getContentProvider(
11851             IApplicationThread caller, String name, int userId, boolean stable) {
11852         enforceNotIsolatedCaller("getContentProvider");
11853         if (caller == null) {
11854             String msg = "null IApplicationThread when getting content provider "
11855                     + name;
11856             Slog.w(TAG, msg);
11857             throw new SecurityException(msg);
11858         }
11859         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11860         // with cross-user grant.
11861         return getContentProviderImpl(caller, name, null, stable, userId);
11862     }
11863
11864     public ContentProviderHolder getContentProviderExternal(
11865             String name, int userId, IBinder token) {
11866         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11867             "Do not have permission in call getContentProviderExternal()");
11868         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11869                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11870         return getContentProviderExternalUnchecked(name, token, userId);
11871     }
11872
11873     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11874             IBinder token, int userId) {
11875         return getContentProviderImpl(null, name, token, true, userId);
11876     }
11877
11878     /**
11879      * Drop a content provider from a ProcessRecord's bookkeeping
11880      */
11881     public void removeContentProvider(IBinder connection, boolean stable) {
11882         enforceNotIsolatedCaller("removeContentProvider");
11883         long ident = Binder.clearCallingIdentity();
11884         try {
11885             synchronized (this) {
11886                 ContentProviderConnection conn;
11887                 try {
11888                     conn = (ContentProviderConnection)connection;
11889                 } catch (ClassCastException e) {
11890                     String msg ="removeContentProvider: " + connection
11891                             + " not a ContentProviderConnection";
11892                     Slog.w(TAG, msg);
11893                     throw new IllegalArgumentException(msg);
11894                 }
11895                 if (conn == null) {
11896                     throw new NullPointerException("connection is null");
11897                 }
11898                 if (decProviderCountLocked(conn, null, null, stable)) {
11899                     updateOomAdjLocked();
11900                 }
11901             }
11902         } finally {
11903             Binder.restoreCallingIdentity(ident);
11904         }
11905     }
11906
11907     public void removeContentProviderExternal(String name, IBinder token) {
11908         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11909             "Do not have permission in call removeContentProviderExternal()");
11910         int userId = UserHandle.getCallingUserId();
11911         long ident = Binder.clearCallingIdentity();
11912         try {
11913             removeContentProviderExternalUnchecked(name, token, userId);
11914         } finally {
11915             Binder.restoreCallingIdentity(ident);
11916         }
11917     }
11918
11919     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11920         synchronized (this) {
11921             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11922             if(cpr == null) {
11923                 //remove from mProvidersByClass
11924                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11925                 return;
11926             }
11927
11928             //update content provider record entry info
11929             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11930             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11931             if (localCpr.hasExternalProcessHandles()) {
11932                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11933                     updateOomAdjLocked();
11934                 } else {
11935                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11936                             + " with no external reference for token: "
11937                             + token + ".");
11938                 }
11939             } else {
11940                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11941                         + " with no external references.");
11942             }
11943         }
11944     }
11945
11946     public final void publishContentProviders(IApplicationThread caller,
11947             List<ContentProviderHolder> providers) {
11948         if (providers == null) {
11949             return;
11950         }
11951
11952         enforceNotIsolatedCaller("publishContentProviders");
11953         synchronized (this) {
11954             final ProcessRecord r = getRecordForAppLocked(caller);
11955             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11956             if (r == null) {
11957                 throw new SecurityException(
11958                         "Unable to find app for caller " + caller
11959                       + " (pid=" + Binder.getCallingPid()
11960                       + ") when publishing content providers");
11961             }
11962
11963             final long origId = Binder.clearCallingIdentity();
11964
11965             final int N = providers.size();
11966             for (int i = 0; i < N; i++) {
11967                 ContentProviderHolder src = providers.get(i);
11968                 if (src == null || src.info == null || src.provider == null) {
11969                     continue;
11970                 }
11971                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11972                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11973                 if (dst != null) {
11974                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11975                     mProviderMap.putProviderByClass(comp, dst);
11976                     String names[] = dst.info.authority.split(";");
11977                     for (int j = 0; j < names.length; j++) {
11978                         mProviderMap.putProviderByName(names[j], dst);
11979                     }
11980
11981                     int launchingCount = mLaunchingProviders.size();
11982                     int j;
11983                     boolean wasInLaunchingProviders = false;
11984                     for (j = 0; j < launchingCount; j++) {
11985                         if (mLaunchingProviders.get(j) == dst) {
11986                             mLaunchingProviders.remove(j);
11987                             wasInLaunchingProviders = true;
11988                             j--;
11989                             launchingCount--;
11990                         }
11991                     }
11992                     if (wasInLaunchingProviders) {
11993                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11994                     }
11995                     synchronized (dst) {
11996                         dst.provider = src.provider;
11997                         dst.proc = r;
11998                         dst.notifyAll();
11999                     }
12000                     updateOomAdjLocked(r, true);
12001                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12002                             src.info.authority);
12003                 }
12004             }
12005
12006             Binder.restoreCallingIdentity(origId);
12007         }
12008     }
12009
12010     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12011         ContentProviderConnection conn;
12012         try {
12013             conn = (ContentProviderConnection)connection;
12014         } catch (ClassCastException e) {
12015             String msg ="refContentProvider: " + connection
12016                     + " not a ContentProviderConnection";
12017             Slog.w(TAG, msg);
12018             throw new IllegalArgumentException(msg);
12019         }
12020         if (conn == null) {
12021             throw new NullPointerException("connection is null");
12022         }
12023
12024         synchronized (this) {
12025             if (stable > 0) {
12026                 conn.numStableIncs += stable;
12027             }
12028             stable = conn.stableCount + stable;
12029             if (stable < 0) {
12030                 throw new IllegalStateException("stableCount < 0: " + stable);
12031             }
12032
12033             if (unstable > 0) {
12034                 conn.numUnstableIncs += unstable;
12035             }
12036             unstable = conn.unstableCount + unstable;
12037             if (unstable < 0) {
12038                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12039             }
12040
12041             if ((stable+unstable) <= 0) {
12042                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12043                         + stable + " unstable=" + unstable);
12044             }
12045             conn.stableCount = stable;
12046             conn.unstableCount = unstable;
12047             return !conn.dead;
12048         }
12049     }
12050
12051     public void unstableProviderDied(IBinder connection) {
12052         ContentProviderConnection conn;
12053         try {
12054             conn = (ContentProviderConnection)connection;
12055         } catch (ClassCastException e) {
12056             String msg ="refContentProvider: " + connection
12057                     + " not a ContentProviderConnection";
12058             Slog.w(TAG, msg);
12059             throw new IllegalArgumentException(msg);
12060         }
12061         if (conn == null) {
12062             throw new NullPointerException("connection is null");
12063         }
12064
12065         // Safely retrieve the content provider associated with the connection.
12066         IContentProvider provider;
12067         synchronized (this) {
12068             provider = conn.provider.provider;
12069         }
12070
12071         if (provider == null) {
12072             // Um, yeah, we're way ahead of you.
12073             return;
12074         }
12075
12076         // Make sure the caller is being honest with us.
12077         if (provider.asBinder().pingBinder()) {
12078             // Er, no, still looks good to us.
12079             synchronized (this) {
12080                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12081                         + " says " + conn + " died, but we don't agree");
12082                 return;
12083             }
12084         }
12085
12086         // Well look at that!  It's dead!
12087         synchronized (this) {
12088             if (conn.provider.provider != provider) {
12089                 // But something changed...  good enough.
12090                 return;
12091             }
12092
12093             ProcessRecord proc = conn.provider.proc;
12094             if (proc == null || proc.thread == null) {
12095                 // Seems like the process is already cleaned up.
12096                 return;
12097             }
12098
12099             // As far as we're concerned, this is just like receiving a
12100             // death notification...  just a bit prematurely.
12101             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12102                     + ") early provider death");
12103             final long ident = Binder.clearCallingIdentity();
12104             try {
12105                 appDiedLocked(proc);
12106             } finally {
12107                 Binder.restoreCallingIdentity(ident);
12108             }
12109         }
12110     }
12111
12112     @Override
12113     public void appNotRespondingViaProvider(IBinder connection) {
12114         enforceCallingPermission(
12115                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12116
12117         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12118         if (conn == null) {
12119             Slog.w(TAG, "ContentProviderConnection is null");
12120             return;
12121         }
12122
12123         final ProcessRecord host = conn.provider.proc;
12124         if (host == null) {
12125             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12126             return;
12127         }
12128
12129         mHandler.post(new Runnable() {
12130             @Override
12131             public void run() {
12132                 mAppErrors.appNotResponding(host, null, null, false,
12133                         "ContentProvider not responding");
12134             }
12135         });
12136     }
12137
12138     public final void installSystemProviders() {
12139         List<ProviderInfo> providers;
12140         synchronized (this) {
12141             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12142             providers = generateApplicationProvidersLocked(app);
12143             if (providers != null) {
12144                 for (int i=providers.size()-1; i>=0; i--) {
12145                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12146                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12147                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12148                                 + ": not system .apk");
12149                         providers.remove(i);
12150                     }
12151                 }
12152             }
12153         }
12154         if (providers != null) {
12155             mSystemThread.installSystemProviders(providers);
12156         }
12157
12158         mConstants.start(mContext.getContentResolver());
12159         mCoreSettingsObserver = new CoreSettingsObserver(this);
12160         mFontScaleSettingObserver = new FontScaleSettingObserver();
12161
12162         // Now that the settings provider is published we can consider sending
12163         // in a rescue party.
12164         RescueParty.onSettingsProviderPublished(mContext);
12165
12166         //mUsageStatsService.monitorPackages();
12167     }
12168
12169     private void startPersistentApps(int matchFlags) {
12170         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12171
12172         synchronized (this) {
12173             try {
12174                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12175                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12176                 for (ApplicationInfo app : apps) {
12177                     if (!"android".equals(app.packageName)) {
12178                         addAppLocked(app, null, false, null /* ABI override */);
12179                     }
12180                 }
12181             } catch (RemoteException ex) {
12182             }
12183         }
12184     }
12185
12186     /**
12187      * When a user is unlocked, we need to install encryption-unaware providers
12188      * belonging to any running apps.
12189      */
12190     private void installEncryptionUnawareProviders(int userId) {
12191         // We're only interested in providers that are encryption unaware, and
12192         // we don't care about uninstalled apps, since there's no way they're
12193         // running at this point.
12194         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12195
12196         synchronized (this) {
12197             final int NP = mProcessNames.getMap().size();
12198             for (int ip = 0; ip < NP; ip++) {
12199                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12200                 final int NA = apps.size();
12201                 for (int ia = 0; ia < NA; ia++) {
12202                     final ProcessRecord app = apps.valueAt(ia);
12203                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12204
12205                     final int NG = app.pkgList.size();
12206                     for (int ig = 0; ig < NG; ig++) {
12207                         try {
12208                             final String pkgName = app.pkgList.keyAt(ig);
12209                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12210                                     .getPackageInfo(pkgName, matchFlags, userId);
12211                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12212                                 for (ProviderInfo pi : pkgInfo.providers) {
12213                                     // TODO: keep in sync with generateApplicationProvidersLocked
12214                                     final boolean processMatch = Objects.equals(pi.processName,
12215                                             app.processName) || pi.multiprocess;
12216                                     final boolean userMatch = isSingleton(pi.processName,
12217                                             pi.applicationInfo, pi.name, pi.flags)
12218                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12219                                     if (processMatch && userMatch) {
12220                                         Log.v(TAG, "Installing " + pi);
12221                                         app.thread.scheduleInstallProvider(pi);
12222                                     } else {
12223                                         Log.v(TAG, "Skipping " + pi);
12224                                     }
12225                                 }
12226                             }
12227                         } catch (RemoteException ignored) {
12228                         }
12229                     }
12230                 }
12231             }
12232         }
12233     }
12234
12235     /**
12236      * Allows apps to retrieve the MIME type of a URI.
12237      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12238      * users, then it does not need permission to access the ContentProvider.
12239      * Either, it needs cross-user uri grants.
12240      *
12241      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12242      *
12243      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12244      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12245      */
12246     public String getProviderMimeType(Uri uri, int userId) {
12247         enforceNotIsolatedCaller("getProviderMimeType");
12248         final String name = uri.getAuthority();
12249         int callingUid = Binder.getCallingUid();
12250         int callingPid = Binder.getCallingPid();
12251         long ident = 0;
12252         boolean clearedIdentity = false;
12253         synchronized (this) {
12254             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12255         }
12256         if (canClearIdentity(callingPid, callingUid, userId)) {
12257             clearedIdentity = true;
12258             ident = Binder.clearCallingIdentity();
12259         }
12260         ContentProviderHolder holder = null;
12261         try {
12262             holder = getContentProviderExternalUnchecked(name, null, userId);
12263             if (holder != null) {
12264                 return holder.provider.getType(uri);
12265             }
12266         } catch (RemoteException e) {
12267             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12268             return null;
12269         } catch (Exception e) {
12270             Log.w(TAG, "Exception while determining type of " + uri, e);
12271             return null;
12272         } finally {
12273             // We need to clear the identity to call removeContentProviderExternalUnchecked
12274             if (!clearedIdentity) {
12275                 ident = Binder.clearCallingIdentity();
12276             }
12277             try {
12278                 if (holder != null) {
12279                     removeContentProviderExternalUnchecked(name, null, userId);
12280                 }
12281             } finally {
12282                 Binder.restoreCallingIdentity(ident);
12283             }
12284         }
12285
12286         return null;
12287     }
12288
12289     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12290         if (UserHandle.getUserId(callingUid) == userId) {
12291             return true;
12292         }
12293         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12294                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12295                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12296                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12297                 return true;
12298         }
12299         return false;
12300     }
12301
12302     // =========================================================
12303     // GLOBAL MANAGEMENT
12304     // =========================================================
12305
12306     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12307             boolean isolated, int isolatedUid) {
12308         String proc = customProcess != null ? customProcess : info.processName;
12309         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12310         final int userId = UserHandle.getUserId(info.uid);
12311         int uid = info.uid;
12312         if (isolated) {
12313             if (isolatedUid == 0) {
12314                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12315                 while (true) {
12316                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12317                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12318                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12319                     }
12320                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12321                     mNextIsolatedProcessUid++;
12322                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12323                         // No process for this uid, use it.
12324                         break;
12325                     }
12326                     stepsLeft--;
12327                     if (stepsLeft <= 0) {
12328                         return null;
12329                     }
12330                 }
12331             } else {
12332                 // Special case for startIsolatedProcess (internal only), where
12333                 // the uid of the isolated process is specified by the caller.
12334                 uid = isolatedUid;
12335             }
12336             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12337
12338             // Register the isolated UID with this application so BatteryStats knows to
12339             // attribute resource usage to the application.
12340             //
12341             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12342             // about the process state of the isolated UID *before* it is registered with the
12343             // owning application.
12344             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12345         }
12346         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12347         if (!mBooted && !mBooting
12348                 && userId == UserHandle.USER_SYSTEM
12349                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12350             r.persistent = true;
12351             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12352         }
12353         addProcessNameLocked(r);
12354         return r;
12355     }
12356
12357     private boolean uidOnBackgroundWhitelist(final int uid) {
12358         final int appId = UserHandle.getAppId(uid);
12359         final int[] whitelist = mBackgroundAppIdWhitelist;
12360         final int N = whitelist.length;
12361         for (int i = 0; i < N; i++) {
12362             if (appId == whitelist[i]) {
12363                 return true;
12364             }
12365         }
12366         return false;
12367     }
12368
12369     @Override
12370     public void backgroundWhitelistUid(final int uid) {
12371         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12372             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12373         }
12374
12375         if (DEBUG_BACKGROUND_CHECK) {
12376             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12377         }
12378         synchronized (this) {
12379             final int N = mBackgroundAppIdWhitelist.length;
12380             int[] newList = new int[N+1];
12381             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12382             newList[N] = UserHandle.getAppId(uid);
12383             mBackgroundAppIdWhitelist = newList;
12384         }
12385     }
12386
12387     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12388             String abiOverride) {
12389         ProcessRecord app;
12390         if (!isolated) {
12391             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12392                     info.uid, true);
12393         } else {
12394             app = null;
12395         }
12396
12397         if (app == null) {
12398             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12399             updateLruProcessLocked(app, false, null);
12400             updateOomAdjLocked();
12401         }
12402
12403         // This package really, really can not be stopped.
12404         try {
12405             AppGlobals.getPackageManager().setPackageStoppedState(
12406                     info.packageName, false, UserHandle.getUserId(app.uid));
12407         } catch (RemoteException e) {
12408         } catch (IllegalArgumentException e) {
12409             Slog.w(TAG, "Failed trying to unstop package "
12410                     + info.packageName + ": " + e);
12411         }
12412
12413         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12414             app.persistent = true;
12415             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12416         }
12417         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12418             mPersistentStartingProcesses.add(app);
12419             startProcessLocked(app, "added application",
12420                     customProcess != null ? customProcess : app.processName, abiOverride,
12421                     null /* entryPoint */, null /* entryPointArgs */);
12422         }
12423
12424         return app;
12425     }
12426
12427     public void unhandledBack() {
12428         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12429                 "unhandledBack()");
12430
12431         synchronized(this) {
12432             final long origId = Binder.clearCallingIdentity();
12433             try {
12434                 getFocusedStack().unhandledBackLocked();
12435             } finally {
12436                 Binder.restoreCallingIdentity(origId);
12437             }
12438         }
12439     }
12440
12441     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12442         enforceNotIsolatedCaller("openContentUri");
12443         final int userId = UserHandle.getCallingUserId();
12444         final Uri uri = Uri.parse(uriString);
12445         String name = uri.getAuthority();
12446         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12447         ParcelFileDescriptor pfd = null;
12448         if (cph != null) {
12449             // We record the binder invoker's uid in thread-local storage before
12450             // going to the content provider to open the file.  Later, in the code
12451             // that handles all permissions checks, we look for this uid and use
12452             // that rather than the Activity Manager's own uid.  The effect is that
12453             // we do the check against the caller's permissions even though it looks
12454             // to the content provider like the Activity Manager itself is making
12455             // the request.
12456             Binder token = new Binder();
12457             sCallerIdentity.set(new Identity(
12458                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12459             try {
12460                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12461             } catch (FileNotFoundException e) {
12462                 // do nothing; pfd will be returned null
12463             } finally {
12464                 // Ensure that whatever happens, we clean up the identity state
12465                 sCallerIdentity.remove();
12466                 // Ensure we're done with the provider.
12467                 removeContentProviderExternalUnchecked(name, null, userId);
12468             }
12469         } else {
12470             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12471         }
12472         return pfd;
12473     }
12474
12475     // Actually is sleeping or shutting down or whatever else in the future
12476     // is an inactive state.
12477     boolean isSleepingOrShuttingDownLocked() {
12478         return isSleepingLocked() || mShuttingDown;
12479     }
12480
12481     boolean isShuttingDownLocked() {
12482         return mShuttingDown;
12483     }
12484
12485     boolean isSleepingLocked() {
12486         return mSleeping;
12487     }
12488
12489     void onWakefulnessChanged(int wakefulness) {
12490         synchronized(this) {
12491             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12492             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12493             mWakefulness = wakefulness;
12494
12495             if (wasAwake != isAwake) {
12496                 // Also update state in a special way for running foreground services UI.
12497                 mServices.updateScreenStateLocked(isAwake);
12498                 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12499                         .sendToTarget();
12500             }
12501         }
12502     }
12503
12504     void finishRunningVoiceLocked() {
12505         if (mRunningVoice != null) {
12506             mRunningVoice = null;
12507             mVoiceWakeLock.release();
12508             updateSleepIfNeededLocked();
12509         }
12510     }
12511
12512     void startTimeTrackingFocusedActivityLocked() {
12513         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12514         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12515             mCurAppTimeTracker.start(resumedActivity.packageName);
12516         }
12517     }
12518
12519     void updateSleepIfNeededLocked() {
12520         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12521         final boolean wasSleeping = mSleeping;
12522
12523         if (!shouldSleep) {
12524             // If wasSleeping is true, we need to wake up activity manager state from when
12525             // we started sleeping. In either case, we need to apply the sleep tokens, which
12526             // will wake up stacks or put them to sleep as appropriate.
12527             if (wasSleeping) {
12528                 mSleeping = false;
12529                 startTimeTrackingFocusedActivityLocked();
12530                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12531                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12532             }
12533             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12534             if (wasSleeping) {
12535                 updateOomAdjLocked();
12536             }
12537         } else if (!mSleeping && shouldSleep) {
12538             mSleeping = true;
12539             if (mCurAppTimeTracker != null) {
12540                 mCurAppTimeTracker.stop();
12541             }
12542             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12543             mStackSupervisor.goingToSleepLocked();
12544             updateOomAdjLocked();
12545         }
12546     }
12547
12548     /** Pokes the task persister. */
12549     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12550         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12551     }
12552
12553     /**
12554      * Notifies all listeners when the pinned stack animation starts.
12555      */
12556     @Override
12557     public void notifyPinnedStackAnimationStarted() {
12558         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12559     }
12560
12561     /**
12562      * Notifies all listeners when the pinned stack animation ends.
12563      */
12564     @Override
12565     public void notifyPinnedStackAnimationEnded() {
12566         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12567     }
12568
12569     @Override
12570     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12571         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12572     }
12573
12574     @Override
12575     public boolean shutdown(int timeout) {
12576         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12577                 != PackageManager.PERMISSION_GRANTED) {
12578             throw new SecurityException("Requires permission "
12579                     + android.Manifest.permission.SHUTDOWN);
12580         }
12581
12582         boolean timedout = false;
12583
12584         synchronized(this) {
12585             mShuttingDown = true;
12586             mStackSupervisor.prepareForShutdownLocked();
12587             updateEventDispatchingLocked();
12588             timedout = mStackSupervisor.shutdownLocked(timeout);
12589         }
12590
12591         mAppOpsService.shutdown();
12592         if (mUsageStatsService != null) {
12593             mUsageStatsService.prepareShutdown();
12594         }
12595         mBatteryStatsService.shutdown();
12596         synchronized (this) {
12597             mProcessStats.shutdownLocked();
12598             notifyTaskPersisterLocked(null, true);
12599         }
12600
12601         return timedout;
12602     }
12603
12604     public final void activitySlept(IBinder token) {
12605         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12606
12607         final long origId = Binder.clearCallingIdentity();
12608
12609         synchronized (this) {
12610             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12611             if (r != null) {
12612                 mStackSupervisor.activitySleptLocked(r);
12613             }
12614         }
12615
12616         Binder.restoreCallingIdentity(origId);
12617     }
12618
12619     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12620         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12621         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12622         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12623             boolean wasRunningVoice = mRunningVoice != null;
12624             mRunningVoice = session;
12625             if (!wasRunningVoice) {
12626                 mVoiceWakeLock.acquire();
12627                 updateSleepIfNeededLocked();
12628             }
12629         }
12630     }
12631
12632     private void updateEventDispatchingLocked() {
12633         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12634     }
12635
12636     @Override
12637     public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12638         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12639                 != PackageManager.PERMISSION_GRANTED) {
12640             throw new SecurityException("Requires permission "
12641                     + android.Manifest.permission.DEVICE_POWER);
12642         }
12643
12644         synchronized(this) {
12645             long ident = Binder.clearCallingIdentity();
12646             try {
12647                 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12648             } finally {
12649                 Binder.restoreCallingIdentity(ident);
12650             }
12651         }
12652
12653         mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12654                 .sendToTarget();
12655     }
12656
12657     @Override
12658     public void notifyLockedProfile(@UserIdInt int userId) {
12659         try {
12660             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12661                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12662             }
12663         } catch (RemoteException ex) {
12664             throw new SecurityException("Fail to check is caller a privileged app", ex);
12665         }
12666
12667         synchronized (this) {
12668             final long ident = Binder.clearCallingIdentity();
12669             try {
12670                 if (mUserController.shouldConfirmCredentials(userId)) {
12671                     if (mKeyguardController.isKeyguardLocked()) {
12672                         // Showing launcher to avoid user entering credential twice.
12673                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12674                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12675                     }
12676                     mStackSupervisor.lockAllProfileTasks(userId);
12677                 }
12678             } finally {
12679                 Binder.restoreCallingIdentity(ident);
12680             }
12681         }
12682     }
12683
12684     @Override
12685     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12686         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12687         synchronized (this) {
12688             final long ident = Binder.clearCallingIdentity();
12689             try {
12690                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12691             } finally {
12692                 Binder.restoreCallingIdentity(ident);
12693             }
12694         }
12695     }
12696
12697     @Override
12698     public void stopAppSwitches() {
12699         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12700                 != PackageManager.PERMISSION_GRANTED) {
12701             throw new SecurityException("viewquires permission "
12702                     + android.Manifest.permission.STOP_APP_SWITCHES);
12703         }
12704
12705         synchronized(this) {
12706             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12707                     + APP_SWITCH_DELAY_TIME;
12708             mDidAppSwitch = false;
12709             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12710             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12711             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12712         }
12713     }
12714
12715     public void resumeAppSwitches() {
12716         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12717                 != PackageManager.PERMISSION_GRANTED) {
12718             throw new SecurityException("Requires permission "
12719                     + android.Manifest.permission.STOP_APP_SWITCHES);
12720         }
12721
12722         synchronized(this) {
12723             // Note that we don't execute any pending app switches... we will
12724             // let those wait until either the timeout, or the next start
12725             // activity request.
12726             mAppSwitchesAllowedTime = 0;
12727         }
12728     }
12729
12730     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12731             int callingPid, int callingUid, String name) {
12732         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12733             return true;
12734         }
12735
12736         int perm = checkComponentPermission(
12737                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12738                 sourceUid, -1, true);
12739         if (perm == PackageManager.PERMISSION_GRANTED) {
12740             return true;
12741         }
12742
12743         // If the actual IPC caller is different from the logical source, then
12744         // also see if they are allowed to control app switches.
12745         if (callingUid != -1 && callingUid != sourceUid) {
12746             perm = checkComponentPermission(
12747                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12748                     callingUid, -1, true);
12749             if (perm == PackageManager.PERMISSION_GRANTED) {
12750                 return true;
12751             }
12752         }
12753
12754         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12755         return false;
12756     }
12757
12758     public void setDebugApp(String packageName, boolean waitForDebugger,
12759             boolean persistent) {
12760         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12761                 "setDebugApp()");
12762
12763         long ident = Binder.clearCallingIdentity();
12764         try {
12765             // Note that this is not really thread safe if there are multiple
12766             // callers into it at the same time, but that's not a situation we
12767             // care about.
12768             if (persistent) {
12769                 final ContentResolver resolver = mContext.getContentResolver();
12770                 Settings.Global.putString(
12771                     resolver, Settings.Global.DEBUG_APP,
12772                     packageName);
12773                 Settings.Global.putInt(
12774                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12775                     waitForDebugger ? 1 : 0);
12776             }
12777
12778             synchronized (this) {
12779                 if (!persistent) {
12780                     mOrigDebugApp = mDebugApp;
12781                     mOrigWaitForDebugger = mWaitForDebugger;
12782                 }
12783                 mDebugApp = packageName;
12784                 mWaitForDebugger = waitForDebugger;
12785                 mDebugTransient = !persistent;
12786                 if (packageName != null) {
12787                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12788                             false, UserHandle.USER_ALL, "set debug app");
12789                 }
12790             }
12791         } finally {
12792             Binder.restoreCallingIdentity(ident);
12793         }
12794     }
12795
12796     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12797         synchronized (this) {
12798             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12799             if (!isDebuggable) {
12800                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12801                     throw new SecurityException("Process not debuggable: " + app.packageName);
12802                 }
12803             }
12804
12805             mTrackAllocationApp = processName;
12806         }
12807     }
12808
12809     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12810         synchronized (this) {
12811             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12812             if (!isDebuggable) {
12813                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12814                     throw new SecurityException("Process not debuggable: " + app.packageName);
12815                 }
12816             }
12817             mProfileApp = processName;
12818
12819             if (mProfilerInfo != null) {
12820                 if (mProfilerInfo.profileFd != null) {
12821                     try {
12822                         mProfilerInfo.profileFd.close();
12823                     } catch (IOException e) {
12824                     }
12825                 }
12826             }
12827             mProfilerInfo = new ProfilerInfo(profilerInfo);
12828             mProfileType = 0;
12829         }
12830     }
12831
12832     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12833         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12834         if (!isDebuggable) {
12835             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12836                 throw new SecurityException("Process not debuggable: " + app.packageName);
12837             }
12838         }
12839         mNativeDebuggingApp = processName;
12840     }
12841
12842     @Override
12843     public void setAlwaysFinish(boolean enabled) {
12844         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12845                 "setAlwaysFinish()");
12846
12847         long ident = Binder.clearCallingIdentity();
12848         try {
12849             Settings.Global.putInt(
12850                     mContext.getContentResolver(),
12851                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12852
12853             synchronized (this) {
12854                 mAlwaysFinishActivities = enabled;
12855             }
12856         } finally {
12857             Binder.restoreCallingIdentity(ident);
12858         }
12859     }
12860
12861     @Override
12862     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12863         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12864                 "setActivityController()");
12865         synchronized (this) {
12866             mController = controller;
12867             mControllerIsAMonkey = imAMonkey;
12868             Watchdog.getInstance().setActivityController(controller);
12869         }
12870     }
12871
12872     @Override
12873     public void setUserIsMonkey(boolean userIsMonkey) {
12874         synchronized (this) {
12875             synchronized (mPidsSelfLocked) {
12876                 final int callingPid = Binder.getCallingPid();
12877                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12878                 if (proc == null) {
12879                     throw new SecurityException("Unknown process: " + callingPid);
12880                 }
12881                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12882                     throw new SecurityException("Only an instrumentation process "
12883                             + "with a UiAutomation can call setUserIsMonkey");
12884                 }
12885             }
12886             mUserIsMonkey = userIsMonkey;
12887         }
12888     }
12889
12890     @Override
12891     public boolean isUserAMonkey() {
12892         synchronized (this) {
12893             // If there is a controller also implies the user is a monkey.
12894             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12895         }
12896     }
12897
12898     /**
12899      * @deprecated This method is only used by a few internal components and it will soon be
12900      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12901      * No new code should be calling it.
12902      */
12903     @Deprecated
12904     @Override
12905     public void requestBugReport(int bugreportType) {
12906         String extraOptions = null;
12907         switch (bugreportType) {
12908             case ActivityManager.BUGREPORT_OPTION_FULL:
12909                 // Default options.
12910                 break;
12911             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12912                 extraOptions = "bugreportplus";
12913                 break;
12914             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12915                 extraOptions = "bugreportremote";
12916                 break;
12917             case ActivityManager.BUGREPORT_OPTION_WEAR:
12918                 extraOptions = "bugreportwear";
12919                 break;
12920             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12921                 extraOptions = "bugreporttelephony";
12922                 break;
12923             default:
12924                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12925                         + bugreportType);
12926         }
12927         // Always log caller, even if it does not have permission to dump.
12928         String type = extraOptions == null ? "bugreport" : extraOptions;
12929         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12930
12931         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12932         if (extraOptions != null) {
12933             SystemProperties.set("dumpstate.options", extraOptions);
12934         }
12935         SystemProperties.set("ctl.start", "bugreport");
12936     }
12937
12938     /**
12939      * @deprecated This method is only used by a few internal components and it will soon be
12940      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12941      * No new code should be calling it.
12942      */
12943     @Deprecated
12944     @Override
12945     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12946
12947         if (!TextUtils.isEmpty(shareTitle)) {
12948             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12949                 String errorStr = "shareTitle should be less than " +
12950                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12951                 throw new IllegalArgumentException(errorStr);
12952             } else {
12953                 if (!TextUtils.isEmpty(shareDescription)) {
12954                     int length;
12955                     try {
12956                         length = shareDescription.getBytes("UTF-8").length;
12957                     } catch (UnsupportedEncodingException e) {
12958                         String errorStr = "shareDescription: UnsupportedEncodingException";
12959                         throw new IllegalArgumentException(errorStr);
12960                     }
12961                     if (length > SystemProperties.PROP_VALUE_MAX) {
12962                         String errorStr = "shareTitle should be less than " +
12963                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12964                         throw new IllegalArgumentException(errorStr);
12965                     } else {
12966                         SystemProperties.set("dumpstate.options.description", shareDescription);
12967                     }
12968                 }
12969                 SystemProperties.set("dumpstate.options.title", shareTitle);
12970             }
12971         }
12972
12973         Slog.d(TAG, "Bugreport notification title " + shareTitle
12974                 + " description " + shareDescription);
12975         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12976     }
12977
12978     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12979         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12980     }
12981
12982     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12983         if (r != null && (r.instr != null || r.usingWrapper)) {
12984             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12985         }
12986         return KEY_DISPATCHING_TIMEOUT;
12987     }
12988
12989     @Override
12990     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12991         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12992                 != PackageManager.PERMISSION_GRANTED) {
12993             throw new SecurityException("Requires permission "
12994                     + android.Manifest.permission.FILTER_EVENTS);
12995         }
12996         ProcessRecord proc;
12997         long timeout;
12998         synchronized (this) {
12999             synchronized (mPidsSelfLocked) {
13000                 proc = mPidsSelfLocked.get(pid);
13001             }
13002             timeout = getInputDispatchingTimeoutLocked(proc);
13003         }
13004
13005         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13006             return -1;
13007         }
13008
13009         return timeout;
13010     }
13011
13012     /**
13013      * Handle input dispatching timeouts.
13014      * Returns whether input dispatching should be aborted or not.
13015      */
13016     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13017             final ActivityRecord activity, final ActivityRecord parent,
13018             final boolean aboveSystem, String reason) {
13019         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13020                 != PackageManager.PERMISSION_GRANTED) {
13021             throw new SecurityException("Requires permission "
13022                     + android.Manifest.permission.FILTER_EVENTS);
13023         }
13024
13025         final String annotation;
13026         if (reason == null) {
13027             annotation = "Input dispatching timed out";
13028         } else {
13029             annotation = "Input dispatching timed out (" + reason + ")";
13030         }
13031
13032         if (proc != null) {
13033             synchronized (this) {
13034                 if (proc.debugging) {
13035                     return false;
13036                 }
13037
13038                 if (proc.instr != null) {
13039                     Bundle info = new Bundle();
13040                     info.putString("shortMsg", "keyDispatchingTimedOut");
13041                     info.putString("longMsg", annotation);
13042                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13043                     return true;
13044                 }
13045             }
13046             mHandler.post(new Runnable() {
13047                 @Override
13048                 public void run() {
13049                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13050                 }
13051             });
13052         }
13053
13054         return true;
13055     }
13056
13057     @Override
13058     public Bundle getAssistContextExtras(int requestType) {
13059         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13060                 null, null, true /* focused */, true /* newSessionId */,
13061                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13062         if (pae == null) {
13063             return null;
13064         }
13065         synchronized (pae) {
13066             while (!pae.haveResult) {
13067                 try {
13068                     pae.wait();
13069                 } catch (InterruptedException e) {
13070                 }
13071             }
13072         }
13073         synchronized (this) {
13074             buildAssistBundleLocked(pae, pae.result);
13075             mPendingAssistExtras.remove(pae);
13076             mUiHandler.removeCallbacks(pae);
13077         }
13078         return pae.extras;
13079     }
13080
13081     @Override
13082     public boolean isAssistDataAllowedOnCurrentActivity() {
13083         int userId;
13084         synchronized (this) {
13085             final ActivityStack focusedStack = getFocusedStack();
13086             if (focusedStack == null || focusedStack.isAssistantStack()) {
13087                 return false;
13088             }
13089
13090             final ActivityRecord activity = focusedStack.topActivity();
13091             if (activity == null) {
13092                 return false;
13093             }
13094             userId = activity.userId;
13095         }
13096         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13097                 Context.DEVICE_POLICY_SERVICE);
13098         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13099     }
13100
13101     @Override
13102     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13103         long ident = Binder.clearCallingIdentity();
13104         try {
13105             synchronized (this) {
13106                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13107                 ActivityRecord top = getFocusedStack().topActivity();
13108                 if (top != caller) {
13109                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13110                             + " is not current top " + top);
13111                     return false;
13112                 }
13113                 if (!top.nowVisible) {
13114                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13115                             + " is not visible");
13116                     return false;
13117                 }
13118             }
13119             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13120                     token);
13121         } finally {
13122             Binder.restoreCallingIdentity(ident);
13123         }
13124     }
13125
13126     @Override
13127     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13128             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13129         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13130                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13131                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13132     }
13133
13134     @Override
13135     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13136             IBinder activityToken, int flags) {
13137         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13138                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13139                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13140     }
13141
13142     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13143             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13144             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13145             int flags) {
13146         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13147                 "enqueueAssistContext()");
13148
13149         synchronized (this) {
13150             ActivityRecord activity = getFocusedStack().topActivity();
13151             if (activity == null) {
13152                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13153                 return null;
13154             }
13155             if (activity.app == null || activity.app.thread == null) {
13156                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13157                 return null;
13158             }
13159             if (focused) {
13160                 if (activityToken != null) {
13161                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13162                     if (activity != caller) {
13163                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13164                                 + " is not current top " + activity);
13165                         return null;
13166                     }
13167                 }
13168             } else {
13169                 activity = ActivityRecord.forTokenLocked(activityToken);
13170                 if (activity == null) {
13171                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13172                             + " couldn't be found");
13173                     return null;
13174                 }
13175                 if (activity.app == null || activity.app.thread == null) {
13176                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13177                     return null;
13178                 }
13179             }
13180
13181             PendingAssistExtras pae;
13182             Bundle extras = new Bundle();
13183             if (args != null) {
13184                 extras.putAll(args);
13185             }
13186             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13187             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13188
13189             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13190                     userHandle);
13191             pae.isHome = activity.isHomeActivity();
13192
13193             // Increment the sessionId if necessary
13194             if (newSessionId) {
13195                 mViSessionId++;
13196             }
13197             try {
13198                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13199                         mViSessionId, flags);
13200                 mPendingAssistExtras.add(pae);
13201                 mUiHandler.postDelayed(pae, timeout);
13202             } catch (RemoteException e) {
13203                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13204                 return null;
13205             }
13206             return pae;
13207         }
13208     }
13209
13210     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13211         IResultReceiver receiver;
13212         synchronized (this) {
13213             mPendingAssistExtras.remove(pae);
13214             receiver = pae.receiver;
13215         }
13216         if (receiver != null) {
13217             // Caller wants result sent back to them.
13218             Bundle sendBundle = new Bundle();
13219             // At least return the receiver extras
13220             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13221                     pae.receiverExtras);
13222             try {
13223                 pae.receiver.send(0, sendBundle);
13224             } catch (RemoteException e) {
13225             }
13226         }
13227     }
13228
13229     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13230         if (result != null) {
13231             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13232         }
13233         if (pae.hint != null) {
13234             pae.extras.putBoolean(pae.hint, true);
13235         }
13236     }
13237
13238     /** Called from an app when assist data is ready. */
13239     @Override
13240     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13241             AssistContent content, Uri referrer) {
13242         PendingAssistExtras pae = (PendingAssistExtras)token;
13243         synchronized (pae) {
13244             pae.result = extras;
13245             pae.structure = structure;
13246             pae.content = content;
13247             if (referrer != null) {
13248                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13249             }
13250             if (structure != null) {
13251                 structure.setHomeActivity(pae.isHome);
13252             }
13253             pae.haveResult = true;
13254             pae.notifyAll();
13255             if (pae.intent == null && pae.receiver == null) {
13256                 // Caller is just waiting for the result.
13257                 return;
13258             }
13259         }
13260         // We are now ready to launch the assist activity.
13261         IResultReceiver sendReceiver = null;
13262         Bundle sendBundle = null;
13263         synchronized (this) {
13264             buildAssistBundleLocked(pae, extras);
13265             boolean exists = mPendingAssistExtras.remove(pae);
13266             mUiHandler.removeCallbacks(pae);
13267             if (!exists) {
13268                 // Timed out.
13269                 return;
13270             }
13271             if ((sendReceiver=pae.receiver) != null) {
13272                 // Caller wants result sent back to them.
13273                 sendBundle = new Bundle();
13274                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13275                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13276                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13277                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13278                         pae.receiverExtras);
13279             }
13280         }
13281         if (sendReceiver != null) {
13282             try {
13283                 sendReceiver.send(0, sendBundle);
13284             } catch (RemoteException e) {
13285             }
13286             return;
13287         }
13288
13289         final long ident = Binder.clearCallingIdentity();
13290         try {
13291             if (TextUtils.equals(pae.intent.getAction(),
13292                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13293                 pae.intent.putExtras(pae.extras);
13294                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13295             } else {
13296                 pae.intent.replaceExtras(pae.extras);
13297                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13298                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13299                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13300                 closeSystemDialogs("assist");
13301
13302                 try {
13303                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13304                 } catch (ActivityNotFoundException e) {
13305                     Slog.w(TAG, "No activity to handle assist action.", e);
13306                 }
13307             }
13308         } finally {
13309             Binder.restoreCallingIdentity(ident);
13310         }
13311     }
13312
13313     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13314             Bundle args) {
13315         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13316                 true /* focused */, true /* newSessionId */, userHandle, args,
13317                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13318     }
13319
13320     public void registerProcessObserver(IProcessObserver observer) {
13321         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13322                 "registerProcessObserver()");
13323         synchronized (this) {
13324             mProcessObservers.register(observer);
13325         }
13326     }
13327
13328     @Override
13329     public void unregisterProcessObserver(IProcessObserver observer) {
13330         synchronized (this) {
13331             mProcessObservers.unregister(observer);
13332         }
13333     }
13334
13335     @Override
13336     public int getUidProcessState(int uid, String callingPackage) {
13337         if (!hasUsageStatsPermission(callingPackage)) {
13338             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13339                     "getUidProcessState");
13340         }
13341
13342         synchronized (this) {
13343             UidRecord uidRec = mActiveUids.get(uid);
13344             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13345         }
13346     }
13347
13348     @Override
13349     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13350             String callingPackage) {
13351         if (!hasUsageStatsPermission(callingPackage)) {
13352             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13353                     "registerUidObserver");
13354         }
13355         synchronized (this) {
13356             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13357                     callingPackage, which, cutpoint));
13358         }
13359     }
13360
13361     @Override
13362     public void unregisterUidObserver(IUidObserver observer) {
13363         synchronized (this) {
13364             mUidObservers.unregister(observer);
13365         }
13366     }
13367
13368     @Override
13369     public boolean convertFromTranslucent(IBinder token) {
13370         final long origId = Binder.clearCallingIdentity();
13371         try {
13372             synchronized (this) {
13373                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13374                 if (r == null) {
13375                     return false;
13376                 }
13377                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13378                 if (translucentChanged) {
13379                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13380                 }
13381                 mWindowManager.setAppFullscreen(token, true);
13382                 return translucentChanged;
13383             }
13384         } finally {
13385             Binder.restoreCallingIdentity(origId);
13386         }
13387     }
13388
13389     @Override
13390     public boolean convertToTranslucent(IBinder token, Bundle options) {
13391         final long origId = Binder.clearCallingIdentity();
13392         try {
13393             synchronized (this) {
13394                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13395                 if (r == null) {
13396                     return false;
13397                 }
13398                 final TaskRecord task = r.getTask();
13399                 int index = task.mActivities.lastIndexOf(r);
13400                 if (index > 0) {
13401                     ActivityRecord under = task.mActivities.get(index - 1);
13402                     under.returningOptions = ActivityOptions.fromBundle(options);
13403                 }
13404                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13405                 if (translucentChanged) {
13406                     r.getStack().convertActivityToTranslucent(r);
13407                 }
13408                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13409                 mWindowManager.setAppFullscreen(token, false);
13410                 return translucentChanged;
13411             }
13412         } finally {
13413             Binder.restoreCallingIdentity(origId);
13414         }
13415     }
13416
13417     @Override
13418     public Bundle getActivityOptions(IBinder token) {
13419         final long origId = Binder.clearCallingIdentity();
13420         try {
13421             synchronized (this) {
13422                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13423                 if (r != null) {
13424                     final ActivityOptions activityOptions = r.takeOptionsLocked();
13425                     return activityOptions == null ? null : activityOptions.toBundle();
13426                 }
13427                 return null;
13428             }
13429         } finally {
13430             Binder.restoreCallingIdentity(origId);
13431         }
13432     }
13433
13434     @Override
13435     public void setImmersive(IBinder token, boolean immersive) {
13436         synchronized(this) {
13437             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13438             if (r == null) {
13439                 throw new IllegalArgumentException();
13440             }
13441             r.immersive = immersive;
13442
13443             // update associated state if we're frontmost
13444             if (r == mStackSupervisor.getResumedActivityLocked()) {
13445                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13446                 applyUpdateLockStateLocked(r);
13447             }
13448         }
13449     }
13450
13451     @Override
13452     public boolean isImmersive(IBinder token) {
13453         synchronized (this) {
13454             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13455             if (r == null) {
13456                 throw new IllegalArgumentException();
13457             }
13458             return r.immersive;
13459         }
13460     }
13461
13462     @Override
13463     public void setVrThread(int tid) {
13464         enforceSystemHasVrFeature();
13465         synchronized (this) {
13466             synchronized (mPidsSelfLocked) {
13467                 final int pid = Binder.getCallingPid();
13468                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13469                 mVrController.setVrThreadLocked(tid, pid, proc);
13470             }
13471         }
13472     }
13473
13474     @Override
13475     public void setPersistentVrThread(int tid) {
13476         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13477             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13478                     + Binder.getCallingPid()
13479                     + ", uid=" + Binder.getCallingUid()
13480                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13481             Slog.w(TAG, msg);
13482             throw new SecurityException(msg);
13483         }
13484         enforceSystemHasVrFeature();
13485         synchronized (this) {
13486             synchronized (mPidsSelfLocked) {
13487                 final int pid = Binder.getCallingPid();
13488                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13489                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13490             }
13491         }
13492     }
13493
13494     /**
13495      * Schedule the given thread a normal scheduling priority.
13496      *
13497      * @param tid the tid of the thread to adjust the scheduling of.
13498      * @param suppressLogs {@code true} if any error logging should be disabled.
13499      *
13500      * @return {@code true} if this succeeded.
13501      */
13502     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13503         try {
13504             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13505             return true;
13506         } catch (IllegalArgumentException e) {
13507             if (!suppressLogs) {
13508                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13509             }
13510         } catch (SecurityException e) {
13511             if (!suppressLogs) {
13512                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13513             }
13514         }
13515         return false;
13516     }
13517
13518     /**
13519      * Schedule the given thread an FIFO scheduling priority.
13520      *
13521      * @param tid the tid of the thread to adjust the scheduling of.
13522      * @param suppressLogs {@code true} if any error logging should be disabled.
13523      *
13524      * @return {@code true} if this succeeded.
13525      */
13526     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13527         try {
13528             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13529             return true;
13530         } catch (IllegalArgumentException e) {
13531             if (!suppressLogs) {
13532                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13533             }
13534         } catch (SecurityException e) {
13535             if (!suppressLogs) {
13536                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13537             }
13538         }
13539         return false;
13540     }
13541
13542     /**
13543      * Check that we have the features required for VR-related API calls, and throw an exception if
13544      * not.
13545      */
13546     private void enforceSystemHasVrFeature() {
13547         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13548             throw new UnsupportedOperationException("VR mode not supported on this device!");
13549         }
13550     }
13551
13552     @Override
13553     public void setRenderThread(int tid) {
13554         synchronized (this) {
13555             ProcessRecord proc;
13556             int pid = Binder.getCallingPid();
13557             if (pid == Process.myPid()) {
13558                 demoteSystemServerRenderThread(tid);
13559                 return;
13560             }
13561             synchronized (mPidsSelfLocked) {
13562                 proc = mPidsSelfLocked.get(pid);
13563                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13564                     // ensure the tid belongs to the process
13565                     if (!isThreadInProcess(pid, tid)) {
13566                         throw new IllegalArgumentException(
13567                             "Render thread does not belong to process");
13568                     }
13569                     proc.renderThreadTid = tid;
13570                     if (DEBUG_OOM_ADJ) {
13571                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13572                     }
13573                     // promote to FIFO now
13574                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13575                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13576                         if (mUseFifoUiScheduling) {
13577                             setThreadScheduler(proc.renderThreadTid,
13578                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13579                         } else {
13580                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13581                         }
13582                     }
13583                 } else {
13584                     if (DEBUG_OOM_ADJ) {
13585                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13586                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13587                                mUseFifoUiScheduling);
13588                     }
13589                 }
13590             }
13591         }
13592     }
13593
13594     /**
13595      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13596      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13597      *
13598      * @param tid the tid of the RenderThread
13599      */
13600     private void demoteSystemServerRenderThread(int tid) {
13601         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13602     }
13603
13604     @Override
13605     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13606         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13607             throw new UnsupportedOperationException("VR mode not supported on this device!");
13608         }
13609
13610         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13611
13612         ActivityRecord r;
13613         synchronized (this) {
13614             r = ActivityRecord.isInStackLocked(token);
13615         }
13616
13617         if (r == null) {
13618             throw new IllegalArgumentException();
13619         }
13620
13621         int err;
13622         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13623                 VrManagerInternal.NO_ERROR) {
13624             return err;
13625         }
13626
13627         synchronized(this) {
13628             r.requestedVrComponent = (enabled) ? packageName : null;
13629
13630             // Update associated state if this activity is currently focused
13631             if (r == mStackSupervisor.getResumedActivityLocked()) {
13632                 applyUpdateVrModeLocked(r);
13633             }
13634             return 0;
13635         }
13636     }
13637
13638     @Override
13639     public boolean isVrModePackageEnabled(ComponentName packageName) {
13640         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13641             throw new UnsupportedOperationException("VR mode not supported on this device!");
13642         }
13643
13644         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13645
13646         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13647                 VrManagerInternal.NO_ERROR;
13648     }
13649
13650     public boolean isTopActivityImmersive() {
13651         enforceNotIsolatedCaller("startActivity");
13652         synchronized (this) {
13653             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13654             return (r != null) ? r.immersive : false;
13655         }
13656     }
13657
13658     /**
13659      * @return whether the system should disable UI modes incompatible with VR mode.
13660      */
13661     boolean shouldDisableNonVrUiLocked() {
13662         return mVrController.shouldDisableNonVrUiLocked();
13663     }
13664
13665     @Override
13666     public boolean isTopOfTask(IBinder token) {
13667         synchronized (this) {
13668             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13669             if (r == null) {
13670                 throw new IllegalArgumentException();
13671             }
13672             return r.getTask().getTopActivity() == r;
13673         }
13674     }
13675
13676     @Override
13677     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13678         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13679             String msg = "Permission Denial: setHasTopUi() from pid="
13680                     + Binder.getCallingPid()
13681                     + ", uid=" + Binder.getCallingUid()
13682                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13683             Slog.w(TAG, msg);
13684             throw new SecurityException(msg);
13685         }
13686         final int pid = Binder.getCallingPid();
13687         final long origId = Binder.clearCallingIdentity();
13688         try {
13689             synchronized (this) {
13690                 boolean changed = false;
13691                 ProcessRecord pr;
13692                 synchronized (mPidsSelfLocked) {
13693                     pr = mPidsSelfLocked.get(pid);
13694                     if (pr == null) {
13695                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13696                         return;
13697                     }
13698                     if (pr.hasTopUi != hasTopUi) {
13699                         if (DEBUG_OOM_ADJ) {
13700                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13701                         }
13702                         pr.hasTopUi = hasTopUi;
13703                         changed = true;
13704                     }
13705                 }
13706                 if (changed) {
13707                     updateOomAdjLocked(pr, true);
13708                 }
13709             }
13710         } finally {
13711             Binder.restoreCallingIdentity(origId);
13712         }
13713     }
13714
13715     public final void enterSafeMode() {
13716         synchronized(this) {
13717             // It only makes sense to do this before the system is ready
13718             // and started launching other packages.
13719             if (!mSystemReady) {
13720                 try {
13721                     AppGlobals.getPackageManager().enterSafeMode();
13722                 } catch (RemoteException e) {
13723                 }
13724             }
13725
13726             mSafeMode = true;
13727         }
13728     }
13729
13730     public final void showSafeModeOverlay() {
13731         View v = LayoutInflater.from(mContext).inflate(
13732                 com.android.internal.R.layout.safe_mode, null);
13733         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13734         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13735         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13736         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13737         lp.gravity = Gravity.BOTTOM | Gravity.START;
13738         lp.format = v.getBackground().getOpacity();
13739         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13740                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13741         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13742         ((WindowManager)mContext.getSystemService(
13743                 Context.WINDOW_SERVICE)).addView(v, lp);
13744     }
13745
13746     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13747         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13748             return;
13749         }
13750         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13751         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13752         synchronized (stats) {
13753             if (mBatteryStatsService.isOnBattery()) {
13754                 mBatteryStatsService.enforceCallingPermission();
13755                 int MY_UID = Binder.getCallingUid();
13756                 final int uid;
13757                 if (sender == null) {
13758                     uid = sourceUid;
13759                 } else {
13760                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13761                 }
13762                 BatteryStatsImpl.Uid.Pkg pkg =
13763                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13764                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13765                 pkg.noteWakeupAlarmLocked(tag);
13766             }
13767         }
13768     }
13769
13770     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13771         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13772             return;
13773         }
13774         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13775         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13776         synchronized (stats) {
13777             mBatteryStatsService.enforceCallingPermission();
13778             int MY_UID = Binder.getCallingUid();
13779             final int uid;
13780             if (sender == null) {
13781                 uid = sourceUid;
13782             } else {
13783                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13784             }
13785             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13786         }
13787     }
13788
13789     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13790         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13791             return;
13792         }
13793         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13794         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13795         synchronized (stats) {
13796             mBatteryStatsService.enforceCallingPermission();
13797             int MY_UID = Binder.getCallingUid();
13798             final int uid;
13799             if (sender == null) {
13800                 uid = sourceUid;
13801             } else {
13802                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13803             }
13804             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13805         }
13806     }
13807
13808     public boolean killPids(int[] pids, String pReason, boolean secure) {
13809         if (Binder.getCallingUid() != SYSTEM_UID) {
13810             throw new SecurityException("killPids only available to the system");
13811         }
13812         String reason = (pReason == null) ? "Unknown" : pReason;
13813         // XXX Note: don't acquire main activity lock here, because the window
13814         // manager calls in with its locks held.
13815
13816         boolean killed = false;
13817         synchronized (mPidsSelfLocked) {
13818             int worstType = 0;
13819             for (int i=0; i<pids.length; i++) {
13820                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13821                 if (proc != null) {
13822                     int type = proc.setAdj;
13823                     if (type > worstType) {
13824                         worstType = type;
13825                     }
13826                 }
13827             }
13828
13829             // If the worst oom_adj is somewhere in the cached proc LRU range,
13830             // then constrain it so we will kill all cached procs.
13831             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13832                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13833                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13834             }
13835
13836             // If this is not a secure call, don't let it kill processes that
13837             // are important.
13838             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13839                 worstType = ProcessList.SERVICE_ADJ;
13840             }
13841
13842             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13843             for (int i=0; i<pids.length; i++) {
13844                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13845                 if (proc == null) {
13846                     continue;
13847                 }
13848                 int adj = proc.setAdj;
13849                 if (adj >= worstType && !proc.killedByAm) {
13850                     proc.kill(reason, true);
13851                     killed = true;
13852                 }
13853             }
13854         }
13855         return killed;
13856     }
13857
13858     @Override
13859     public void killUid(int appId, int userId, String reason) {
13860         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13861         synchronized (this) {
13862             final long identity = Binder.clearCallingIdentity();
13863             try {
13864                 killPackageProcessesLocked(null, appId, userId,
13865                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13866                         reason != null ? reason : "kill uid");
13867             } finally {
13868                 Binder.restoreCallingIdentity(identity);
13869             }
13870         }
13871     }
13872
13873     @Override
13874     public boolean killProcessesBelowForeground(String reason) {
13875         if (Binder.getCallingUid() != SYSTEM_UID) {
13876             throw new SecurityException("killProcessesBelowForeground() only available to system");
13877         }
13878
13879         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13880     }
13881
13882     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13883         if (Binder.getCallingUid() != SYSTEM_UID) {
13884             throw new SecurityException("killProcessesBelowAdj() only available to system");
13885         }
13886
13887         boolean killed = false;
13888         synchronized (mPidsSelfLocked) {
13889             final int size = mPidsSelfLocked.size();
13890             for (int i = 0; i < size; i++) {
13891                 final int pid = mPidsSelfLocked.keyAt(i);
13892                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13893                 if (proc == null) continue;
13894
13895                 final int adj = proc.setAdj;
13896                 if (adj > belowAdj && !proc.killedByAm) {
13897                     proc.kill(reason, true);
13898                     killed = true;
13899                 }
13900             }
13901         }
13902         return killed;
13903     }
13904
13905     @Override
13906     public void hang(final IBinder who, boolean allowRestart) {
13907         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13908                 != PackageManager.PERMISSION_GRANTED) {
13909             throw new SecurityException("Requires permission "
13910                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13911         }
13912
13913         final IBinder.DeathRecipient death = new DeathRecipient() {
13914             @Override
13915             public void binderDied() {
13916                 synchronized (this) {
13917                     notifyAll();
13918                 }
13919             }
13920         };
13921
13922         try {
13923             who.linkToDeath(death, 0);
13924         } catch (RemoteException e) {
13925             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13926             return;
13927         }
13928
13929         synchronized (this) {
13930             Watchdog.getInstance().setAllowRestart(allowRestart);
13931             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13932             synchronized (death) {
13933                 while (who.isBinderAlive()) {
13934                     try {
13935                         death.wait();
13936                     } catch (InterruptedException e) {
13937                     }
13938                 }
13939             }
13940             Watchdog.getInstance().setAllowRestart(true);
13941         }
13942     }
13943
13944     @Override
13945     public void restart() {
13946         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13947                 != PackageManager.PERMISSION_GRANTED) {
13948             throw new SecurityException("Requires permission "
13949                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13950         }
13951
13952         Log.i(TAG, "Sending shutdown broadcast...");
13953
13954         BroadcastReceiver br = new BroadcastReceiver() {
13955             @Override public void onReceive(Context context, Intent intent) {
13956                 // Now the broadcast is done, finish up the low-level shutdown.
13957                 Log.i(TAG, "Shutting down activity manager...");
13958                 shutdown(10000);
13959                 Log.i(TAG, "Shutdown complete, restarting!");
13960                 killProcess(myPid());
13961                 System.exit(10);
13962             }
13963         };
13964
13965         // First send the high-level shut down broadcast.
13966         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13967         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13968         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13969         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13970         mContext.sendOrderedBroadcastAsUser(intent,
13971                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13972         */
13973         br.onReceive(mContext, intent);
13974     }
13975
13976     private long getLowRamTimeSinceIdle(long now) {
13977         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13978     }
13979
13980     @Override
13981     public void performIdleMaintenance() {
13982         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13983                 != PackageManager.PERMISSION_GRANTED) {
13984             throw new SecurityException("Requires permission "
13985                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13986         }
13987
13988         synchronized (this) {
13989             final long now = SystemClock.uptimeMillis();
13990             final long timeSinceLastIdle = now - mLastIdleTime;
13991             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13992             mLastIdleTime = now;
13993             mLowRamTimeSinceLastIdle = 0;
13994             if (mLowRamStartTime != 0) {
13995                 mLowRamStartTime = now;
13996             }
13997
13998             StringBuilder sb = new StringBuilder(128);
13999             sb.append("Idle maintenance over ");
14000             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14001             sb.append(" low RAM for ");
14002             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14003             Slog.i(TAG, sb.toString());
14004
14005             // If at least 1/3 of our time since the last idle period has been spent
14006             // with RAM low, then we want to kill processes.
14007             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14008
14009             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14010                 ProcessRecord proc = mLruProcesses.get(i);
14011                 if (proc.notCachedSinceIdle) {
14012                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14013                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14014                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14015                         if (doKilling && proc.initialIdlePss != 0
14016                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14017                             sb = new StringBuilder(128);
14018                             sb.append("Kill");
14019                             sb.append(proc.processName);
14020                             sb.append(" in idle maint: pss=");
14021                             sb.append(proc.lastPss);
14022                             sb.append(", swapPss=");
14023                             sb.append(proc.lastSwapPss);
14024                             sb.append(", initialPss=");
14025                             sb.append(proc.initialIdlePss);
14026                             sb.append(", period=");
14027                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14028                             sb.append(", lowRamPeriod=");
14029                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14030                             Slog.wtfQuiet(TAG, sb.toString());
14031                             proc.kill("idle maint (pss " + proc.lastPss
14032                                     + " from " + proc.initialIdlePss + ")", true);
14033                         }
14034                     }
14035                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14036                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14037                     proc.notCachedSinceIdle = true;
14038                     proc.initialIdlePss = 0;
14039                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14040                             mTestPssMode, isSleepingLocked(), now);
14041                 }
14042             }
14043
14044             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14045             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14046         }
14047     }
14048
14049     @Override
14050     public void sendIdleJobTrigger() {
14051         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14052                 != PackageManager.PERMISSION_GRANTED) {
14053             throw new SecurityException("Requires permission "
14054                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14055         }
14056
14057         final long ident = Binder.clearCallingIdentity();
14058         try {
14059             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14060                     .setPackage("android")
14061                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14062             broadcastIntent(null, intent, null, null, 0, null, null, null,
14063                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14064         } finally {
14065             Binder.restoreCallingIdentity(ident);
14066         }
14067     }
14068
14069     private void retrieveSettings() {
14070         final ContentResolver resolver = mContext.getContentResolver();
14071         final boolean freeformWindowManagement =
14072                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14073                         || Settings.Global.getInt(
14074                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14075
14076         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14077         final boolean supportsPictureInPicture = supportsMultiWindow &&
14078                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14079         final boolean supportsSplitScreenMultiWindow =
14080                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14081         final boolean supportsMultiDisplay = mContext.getPackageManager()
14082                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14083         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14084         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14085         final boolean alwaysFinishActivities =
14086                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14087         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14088         final boolean forceResizable = Settings.Global.getInt(
14089                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14090         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14091                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14092         final boolean supportsLeanbackOnly =
14093                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14094
14095         // Transfer any global setting for forcing RTL layout, into a System Property
14096         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14097
14098         final Configuration configuration = new Configuration();
14099         Settings.System.getConfiguration(resolver, configuration);
14100         if (forceRtl) {
14101             // This will take care of setting the correct layout direction flags
14102             configuration.setLayoutDirection(configuration.locale);
14103         }
14104
14105         synchronized (this) {
14106             mDebugApp = mOrigDebugApp = debugApp;
14107             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14108             mAlwaysFinishActivities = alwaysFinishActivities;
14109             mSupportsLeanbackOnly = supportsLeanbackOnly;
14110             mForceResizableActivities = forceResizable;
14111             final boolean multiWindowFormEnabled = freeformWindowManagement
14112                     || supportsSplitScreenMultiWindow
14113                     || supportsPictureInPicture
14114                     || supportsMultiDisplay;
14115             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14116                 mSupportsMultiWindow = true;
14117                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14118                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14119                 mSupportsPictureInPicture = supportsPictureInPicture;
14120                 mSupportsMultiDisplay = supportsMultiDisplay;
14121             } else {
14122                 mSupportsMultiWindow = false;
14123                 mSupportsFreeformWindowManagement = false;
14124                 mSupportsSplitScreenMultiWindow = false;
14125                 mSupportsPictureInPicture = false;
14126                 mSupportsMultiDisplay = false;
14127             }
14128             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14129             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14130             // This happens before any activities are started, so we can change global configuration
14131             // in-place.
14132             updateConfigurationLocked(configuration, null, true);
14133             final Configuration globalConfig = getGlobalConfiguration();
14134             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14135
14136             // Load resources only after the current configuration has been set.
14137             final Resources res = mContext.getResources();
14138             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14139             mThumbnailWidth = res.getDimensionPixelSize(
14140                     com.android.internal.R.dimen.thumbnail_width);
14141             mThumbnailHeight = res.getDimensionPixelSize(
14142                     com.android.internal.R.dimen.thumbnail_height);
14143             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14144                     com.android.internal.R.string.config_appsNotReportingCrashes));
14145             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14146                     com.android.internal.R.bool.config_customUserSwitchUi);
14147             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14148                 mFullscreenThumbnailScale = (float) res
14149                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14150                     (float) globalConfig.screenWidthDp;
14151             } else {
14152                 mFullscreenThumbnailScale = res.getFraction(
14153                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14154             }
14155             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14156         }
14157     }
14158
14159     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14160         traceLog.traceBegin("PhaseActivityManagerReady");
14161         synchronized(this) {
14162             if (mSystemReady) {
14163                 // If we're done calling all the receivers, run the next "boot phase" passed in
14164                 // by the SystemServer
14165                 if (goingCallback != null) {
14166                     goingCallback.run();
14167                 }
14168                 return;
14169             }
14170
14171             mLocalDeviceIdleController
14172                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14173             mAssistUtils = new AssistUtils(mContext);
14174             mVrController.onSystemReady();
14175             // Make sure we have the current profile info, since it is needed for security checks.
14176             mUserController.onSystemReady();
14177             mRecentTasks.onSystemReadyLocked();
14178             mAppOpsService.systemReady();
14179             mSystemReady = true;
14180         }
14181
14182         try {
14183             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14184                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14185                     .getSerial();
14186         } catch (RemoteException e) {}
14187
14188         ArrayList<ProcessRecord> procsToKill = null;
14189         synchronized(mPidsSelfLocked) {
14190             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14191                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14192                 if (!isAllowedWhileBooting(proc.info)){
14193                     if (procsToKill == null) {
14194                         procsToKill = new ArrayList<ProcessRecord>();
14195                     }
14196                     procsToKill.add(proc);
14197                 }
14198             }
14199         }
14200
14201         synchronized(this) {
14202             if (procsToKill != null) {
14203                 for (int i=procsToKill.size()-1; i>=0; i--) {
14204                     ProcessRecord proc = procsToKill.get(i);
14205                     Slog.i(TAG, "Removing system update proc: " + proc);
14206                     removeProcessLocked(proc, true, false, "system update done");
14207                 }
14208             }
14209
14210             // Now that we have cleaned up any update processes, we
14211             // are ready to start launching real processes and know that
14212             // we won't trample on them any more.
14213             mProcessesReady = true;
14214         }
14215
14216         Slog.i(TAG, "System now ready");
14217         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14218             SystemClock.uptimeMillis());
14219
14220         synchronized(this) {
14221             // Make sure we have no pre-ready processes sitting around.
14222
14223             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14224                 ResolveInfo ri = mContext.getPackageManager()
14225                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14226                                 STOCK_PM_FLAGS);
14227                 CharSequence errorMsg = null;
14228                 if (ri != null) {
14229                     ActivityInfo ai = ri.activityInfo;
14230                     ApplicationInfo app = ai.applicationInfo;
14231                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14232                         mTopAction = Intent.ACTION_FACTORY_TEST;
14233                         mTopData = null;
14234                         mTopComponent = new ComponentName(app.packageName,
14235                                 ai.name);
14236                     } else {
14237                         errorMsg = mContext.getResources().getText(
14238                                 com.android.internal.R.string.factorytest_not_system);
14239                     }
14240                 } else {
14241                     errorMsg = mContext.getResources().getText(
14242                             com.android.internal.R.string.factorytest_no_action);
14243                 }
14244                 if (errorMsg != null) {
14245                     mTopAction = null;
14246                     mTopData = null;
14247                     mTopComponent = null;
14248                     Message msg = Message.obtain();
14249                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14250                     msg.getData().putCharSequence("msg", errorMsg);
14251                     mUiHandler.sendMessage(msg);
14252                 }
14253             }
14254         }
14255
14256         retrieveSettings();
14257         final int currentUserId;
14258         synchronized (this) {
14259             currentUserId = mUserController.getCurrentUserIdLocked();
14260             readGrantedUriPermissionsLocked();
14261         }
14262
14263         if (goingCallback != null) goingCallback.run();
14264         traceLog.traceBegin("ActivityManagerStartApps");
14265         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14266                 Integer.toString(currentUserId), currentUserId);
14267         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14268                 Integer.toString(currentUserId), currentUserId);
14269         mSystemServiceManager.startUser(currentUserId);
14270
14271         synchronized (this) {
14272             // Only start up encryption-aware persistent apps; once user is
14273             // unlocked we'll come back around and start unaware apps
14274             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14275
14276             // Start up initial activity.
14277             mBooting = true;
14278             // Enable home activity for system user, so that the system can always boot. We don't
14279             // do this when the system user is not setup since the setup wizard should be the one
14280             // to handle home activity in this case.
14281             if (UserManager.isSplitSystemUser() &&
14282                     Settings.Secure.getInt(mContext.getContentResolver(),
14283                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14284                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14285                 try {
14286                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14287                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14288                             UserHandle.USER_SYSTEM);
14289                 } catch (RemoteException e) {
14290                     throw e.rethrowAsRuntimeException();
14291                 }
14292             }
14293             startHomeActivityLocked(currentUserId, "systemReady");
14294
14295             try {
14296                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14297                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14298                             + " data partition or your device will be unstable.");
14299                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14300                 }
14301             } catch (RemoteException e) {
14302             }
14303
14304             if (!Build.isBuildConsistent()) {
14305                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14306                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14307             }
14308
14309             long ident = Binder.clearCallingIdentity();
14310             try {
14311                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14312                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14313                         | Intent.FLAG_RECEIVER_FOREGROUND);
14314                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14315                 broadcastIntentLocked(null, null, intent,
14316                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14317                         null, false, false, MY_PID, SYSTEM_UID,
14318                         currentUserId);
14319                 intent = new Intent(Intent.ACTION_USER_STARTING);
14320                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14321                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14322                 broadcastIntentLocked(null, null, intent,
14323                         null, new IIntentReceiver.Stub() {
14324                             @Override
14325                             public void performReceive(Intent intent, int resultCode, String data,
14326                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14327                                     throws RemoteException {
14328                             }
14329                         }, 0, null, null,
14330                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14331                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14332             } catch (Throwable t) {
14333                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14334             } finally {
14335                 Binder.restoreCallingIdentity(ident);
14336             }
14337             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14338             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14339             traceLog.traceEnd(); // ActivityManagerStartApps
14340             traceLog.traceEnd(); // PhaseActivityManagerReady
14341         }
14342     }
14343
14344     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14345         synchronized (this) {
14346             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14347         }
14348     }
14349
14350     void skipCurrentReceiverLocked(ProcessRecord app) {
14351         for (BroadcastQueue queue : mBroadcastQueues) {
14352             queue.skipCurrentReceiverLocked(app);
14353         }
14354     }
14355
14356     /**
14357      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14358      * The application process will exit immediately after this call returns.
14359      * @param app object of the crashing app, null for the system server
14360      * @param crashInfo describing the exception
14361      */
14362     public void handleApplicationCrash(IBinder app,
14363             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14364         ProcessRecord r = findAppProcess(app, "Crash");
14365         final String processName = app == null ? "system_server"
14366                 : (r == null ? "unknown" : r.processName);
14367
14368         handleApplicationCrashInner("crash", r, processName, crashInfo);
14369     }
14370
14371     /* Native crash reporting uses this inner version because it needs to be somewhat
14372      * decoupled from the AM-managed cleanup lifecycle
14373      */
14374     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14375             ApplicationErrorReport.CrashInfo crashInfo) {
14376         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14377                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14378                 r == null ? -1 : r.info.flags,
14379                 crashInfo.exceptionClassName,
14380                 crashInfo.exceptionMessage,
14381                 crashInfo.throwFileName,
14382                 crashInfo.throwLineNumber);
14383
14384         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14385
14386         mAppErrors.crashApplication(r, crashInfo);
14387     }
14388
14389     public void handleApplicationStrictModeViolation(
14390             IBinder app,
14391             int violationMask,
14392             StrictMode.ViolationInfo info) {
14393         ProcessRecord r = findAppProcess(app, "StrictMode");
14394         if (r == null) {
14395             return;
14396         }
14397
14398         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14399             Integer stackFingerprint = info.hashCode();
14400             boolean logIt = true;
14401             synchronized (mAlreadyLoggedViolatedStacks) {
14402                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14403                     logIt = false;
14404                     // TODO: sub-sample into EventLog for these, with
14405                     // the info.durationMillis?  Then we'd get
14406                     // the relative pain numbers, without logging all
14407                     // the stack traces repeatedly.  We'd want to do
14408                     // likewise in the client code, which also does
14409                     // dup suppression, before the Binder call.
14410                 } else {
14411                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14412                         mAlreadyLoggedViolatedStacks.clear();
14413                     }
14414                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14415                 }
14416             }
14417             if (logIt) {
14418                 logStrictModeViolationToDropBox(r, info);
14419             }
14420         }
14421
14422         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14423             AppErrorResult result = new AppErrorResult();
14424             synchronized (this) {
14425                 final long origId = Binder.clearCallingIdentity();
14426
14427                 Message msg = Message.obtain();
14428                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14429                 HashMap<String, Object> data = new HashMap<String, Object>();
14430                 data.put("result", result);
14431                 data.put("app", r);
14432                 data.put("violationMask", violationMask);
14433                 data.put("info", info);
14434                 msg.obj = data;
14435                 mUiHandler.sendMessage(msg);
14436
14437                 Binder.restoreCallingIdentity(origId);
14438             }
14439             int res = result.get();
14440             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14441         }
14442     }
14443
14444     // Depending on the policy in effect, there could be a bunch of
14445     // these in quick succession so we try to batch these together to
14446     // minimize disk writes, number of dropbox entries, and maximize
14447     // compression, by having more fewer, larger records.
14448     private void logStrictModeViolationToDropBox(
14449             ProcessRecord process,
14450             StrictMode.ViolationInfo info) {
14451         if (info == null) {
14452             return;
14453         }
14454         final boolean isSystemApp = process == null ||
14455                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14456                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14457         final String processName = process == null ? "unknown" : process.processName;
14458         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14459         final DropBoxManager dbox = (DropBoxManager)
14460                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14461
14462         // Exit early if the dropbox isn't configured to accept this report type.
14463         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14464
14465         boolean bufferWasEmpty;
14466         boolean needsFlush;
14467         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14468         synchronized (sb) {
14469             bufferWasEmpty = sb.length() == 0;
14470             appendDropBoxProcessHeaders(process, processName, sb);
14471             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14472             sb.append("System-App: ").append(isSystemApp).append("\n");
14473             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14474             if (info.violationNumThisLoop != 0) {
14475                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14476             }
14477             if (info.numAnimationsRunning != 0) {
14478                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14479             }
14480             if (info.broadcastIntentAction != null) {
14481                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14482             }
14483             if (info.durationMillis != -1) {
14484                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14485             }
14486             if (info.numInstances != -1) {
14487                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14488             }
14489             if (info.tags != null) {
14490                 for (String tag : info.tags) {
14491                     sb.append("Span-Tag: ").append(tag).append("\n");
14492                 }
14493             }
14494             sb.append("\n");
14495             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14496                 sb.append(info.crashInfo.stackTrace);
14497                 sb.append("\n");
14498             }
14499             if (info.message != null) {
14500                 sb.append(info.message);
14501                 sb.append("\n");
14502             }
14503
14504             // Only buffer up to ~64k.  Various logging bits truncate
14505             // things at 128k.
14506             needsFlush = (sb.length() > 64 * 1024);
14507         }
14508
14509         // Flush immediately if the buffer's grown too large, or this
14510         // is a non-system app.  Non-system apps are isolated with a
14511         // different tag & policy and not batched.
14512         //
14513         // Batching is useful during internal testing with
14514         // StrictMode settings turned up high.  Without batching,
14515         // thousands of separate files could be created on boot.
14516         if (!isSystemApp || needsFlush) {
14517             new Thread("Error dump: " + dropboxTag) {
14518                 @Override
14519                 public void run() {
14520                     String report;
14521                     synchronized (sb) {
14522                         report = sb.toString();
14523                         sb.delete(0, sb.length());
14524                         sb.trimToSize();
14525                     }
14526                     if (report.length() != 0) {
14527                         dbox.addText(dropboxTag, report);
14528                     }
14529                 }
14530             }.start();
14531             return;
14532         }
14533
14534         // System app batching:
14535         if (!bufferWasEmpty) {
14536             // An existing dropbox-writing thread is outstanding, so
14537             // we don't need to start it up.  The existing thread will
14538             // catch the buffer appends we just did.
14539             return;
14540         }
14541
14542         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14543         // (After this point, we shouldn't access AMS internal data structures.)
14544         new Thread("Error dump: " + dropboxTag) {
14545             @Override
14546             public void run() {
14547                 // 5 second sleep to let stacks arrive and be batched together
14548                 try {
14549                     Thread.sleep(5000);  // 5 seconds
14550                 } catch (InterruptedException e) {}
14551
14552                 String errorReport;
14553                 synchronized (mStrictModeBuffer) {
14554                     errorReport = mStrictModeBuffer.toString();
14555                     if (errorReport.length() == 0) {
14556                         return;
14557                     }
14558                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14559                     mStrictModeBuffer.trimToSize();
14560                 }
14561                 dbox.addText(dropboxTag, errorReport);
14562             }
14563         }.start();
14564     }
14565
14566     /**
14567      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14568      * @param app object of the crashing app, null for the system server
14569      * @param tag reported by the caller
14570      * @param system whether this wtf is coming from the system
14571      * @param crashInfo describing the context of the error
14572      * @return true if the process should exit immediately (WTF is fatal)
14573      */
14574     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14575             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14576         final int callingUid = Binder.getCallingUid();
14577         final int callingPid = Binder.getCallingPid();
14578
14579         if (system) {
14580             // If this is coming from the system, we could very well have low-level
14581             // system locks held, so we want to do this all asynchronously.  And we
14582             // never want this to become fatal, so there is that too.
14583             mHandler.post(new Runnable() {
14584                 @Override public void run() {
14585                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14586                 }
14587             });
14588             return false;
14589         }
14590
14591         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14592                 crashInfo);
14593
14594         final boolean isFatal = Build.IS_ENG || Settings.Global
14595                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14596         final boolean isSystem = (r == null) || r.persistent;
14597
14598         if (isFatal && !isSystem) {
14599             mAppErrors.crashApplication(r, crashInfo);
14600             return true;
14601         } else {
14602             return false;
14603         }
14604     }
14605
14606     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14607             final ApplicationErrorReport.CrashInfo crashInfo) {
14608         final ProcessRecord r = findAppProcess(app, "WTF");
14609         final String processName = app == null ? "system_server"
14610                 : (r == null ? "unknown" : r.processName);
14611
14612         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14613                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14614
14615         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14616
14617         return r;
14618     }
14619
14620     /**
14621      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14622      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14623      */
14624     private ProcessRecord findAppProcess(IBinder app, String reason) {
14625         if (app == null) {
14626             return null;
14627         }
14628
14629         synchronized (this) {
14630             final int NP = mProcessNames.getMap().size();
14631             for (int ip=0; ip<NP; ip++) {
14632                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14633                 final int NA = apps.size();
14634                 for (int ia=0; ia<NA; ia++) {
14635                     ProcessRecord p = apps.valueAt(ia);
14636                     if (p.thread != null && p.thread.asBinder() == app) {
14637                         return p;
14638                     }
14639                 }
14640             }
14641
14642             Slog.w(TAG, "Can't find mystery application for " + reason
14643                     + " from pid=" + Binder.getCallingPid()
14644                     + " uid=" + Binder.getCallingUid() + ": " + app);
14645             return null;
14646         }
14647     }
14648
14649     /**
14650      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14651      * to append various headers to the dropbox log text.
14652      */
14653     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14654             StringBuilder sb) {
14655         // Watchdog thread ends up invoking this function (with
14656         // a null ProcessRecord) to add the stack file to dropbox.
14657         // Do not acquire a lock on this (am) in such cases, as it
14658         // could cause a potential deadlock, if and when watchdog
14659         // is invoked due to unavailability of lock on am and it
14660         // would prevent watchdog from killing system_server.
14661         if (process == null) {
14662             sb.append("Process: ").append(processName).append("\n");
14663             return;
14664         }
14665         // Note: ProcessRecord 'process' is guarded by the service
14666         // instance.  (notably process.pkgList, which could otherwise change
14667         // concurrently during execution of this method)
14668         synchronized (this) {
14669             sb.append("Process: ").append(processName).append("\n");
14670             sb.append("PID: ").append(process.pid).append("\n");
14671             int flags = process.info.flags;
14672             IPackageManager pm = AppGlobals.getPackageManager();
14673             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14674             for (int ip=0; ip<process.pkgList.size(); ip++) {
14675                 String pkg = process.pkgList.keyAt(ip);
14676                 sb.append("Package: ").append(pkg);
14677                 try {
14678                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14679                     if (pi != null) {
14680                         sb.append(" v").append(pi.versionCode);
14681                         if (pi.versionName != null) {
14682                             sb.append(" (").append(pi.versionName).append(")");
14683                         }
14684                     }
14685                 } catch (RemoteException e) {
14686                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14687                 }
14688                 sb.append("\n");
14689             }
14690             if (process.info.isInstantApp()) {
14691                 sb.append("Instant-App: true\n");
14692             }
14693         }
14694     }
14695
14696     private static String processClass(ProcessRecord process) {
14697         if (process == null || process.pid == MY_PID) {
14698             return "system_server";
14699         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14700             return "system_app";
14701         } else {
14702             return "data_app";
14703         }
14704     }
14705
14706     private volatile long mWtfClusterStart;
14707     private volatile int mWtfClusterCount;
14708
14709     /**
14710      * Write a description of an error (crash, WTF, ANR) to the drop box.
14711      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14712      * @param process which caused the error, null means the system server
14713      * @param activity which triggered the error, null if unknown
14714      * @param parent activity related to the error, null if unknown
14715      * @param subject line related to the error, null if absent
14716      * @param report in long form describing the error, null if absent
14717      * @param dataFile text file to include in the report, null if none
14718      * @param crashInfo giving an application stack trace, null if absent
14719      */
14720     public void addErrorToDropBox(String eventType,
14721             ProcessRecord process, String processName, ActivityRecord activity,
14722             ActivityRecord parent, String subject,
14723             final String report, final File dataFile,
14724             final ApplicationErrorReport.CrashInfo crashInfo) {
14725         // NOTE -- this must never acquire the ActivityManagerService lock,
14726         // otherwise the watchdog may be prevented from resetting the system.
14727
14728         // Bail early if not published yet
14729         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14730         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14731
14732         // Exit early if the dropbox isn't configured to accept this report type.
14733         final String dropboxTag = processClass(process) + "_" + eventType;
14734         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14735
14736         // Rate-limit how often we're willing to do the heavy lifting below to
14737         // collect and record logs; currently 5 logs per 10 second period.
14738         final long now = SystemClock.elapsedRealtime();
14739         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14740             mWtfClusterStart = now;
14741             mWtfClusterCount = 1;
14742         } else {
14743             if (mWtfClusterCount++ >= 5) return;
14744         }
14745
14746         final StringBuilder sb = new StringBuilder(1024);
14747         appendDropBoxProcessHeaders(process, processName, sb);
14748         if (process != null) {
14749             sb.append("Foreground: ")
14750                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14751                     .append("\n");
14752         }
14753         if (activity != null) {
14754             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14755         }
14756         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14757             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14758         }
14759         if (parent != null && parent != activity) {
14760             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14761         }
14762         if (subject != null) {
14763             sb.append("Subject: ").append(subject).append("\n");
14764         }
14765         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14766         if (Debug.isDebuggerConnected()) {
14767             sb.append("Debugger: Connected\n");
14768         }
14769         sb.append("\n");
14770
14771         // Do the rest in a worker thread to avoid blocking the caller on I/O
14772         // (After this point, we shouldn't access AMS internal data structures.)
14773         Thread worker = new Thread("Error dump: " + dropboxTag) {
14774             @Override
14775             public void run() {
14776                 if (report != null) {
14777                     sb.append(report);
14778                 }
14779
14780                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14781                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14782                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14783                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14784
14785                 if (dataFile != null && maxDataFileSize > 0) {
14786                     try {
14787                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14788                                     "\n\n[[TRUNCATED]]"));
14789                     } catch (IOException e) {
14790                         Slog.e(TAG, "Error reading " + dataFile, e);
14791                     }
14792                 }
14793                 if (crashInfo != null && crashInfo.stackTrace != null) {
14794                     sb.append(crashInfo.stackTrace);
14795                 }
14796
14797                 if (lines > 0) {
14798                     sb.append("\n");
14799
14800                     // Merge several logcat streams, and take the last N lines
14801                     InputStreamReader input = null;
14802                     try {
14803                         java.lang.Process logcat = new ProcessBuilder(
14804                                 "/system/bin/timeout", "-k", "15s", "10s",
14805                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14806                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14807                                         .redirectErrorStream(true).start();
14808
14809                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14810                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14811                         input = new InputStreamReader(logcat.getInputStream());
14812
14813                         int num;
14814                         char[] buf = new char[8192];
14815                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14816                     } catch (IOException e) {
14817                         Slog.e(TAG, "Error running logcat", e);
14818                     } finally {
14819                         if (input != null) try { input.close(); } catch (IOException e) {}
14820                     }
14821                 }
14822
14823                 dbox.addText(dropboxTag, sb.toString());
14824             }
14825         };
14826
14827         if (process == null) {
14828             // If process is null, we are being called from some internal code
14829             // and may be about to die -- run this synchronously.
14830             worker.run();
14831         } else {
14832             worker.start();
14833         }
14834     }
14835
14836     @Override
14837     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14838         enforceNotIsolatedCaller("getProcessesInErrorState");
14839         // assume our apps are happy - lazy create the list
14840         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14841
14842         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14843                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14844         int userId = UserHandle.getUserId(Binder.getCallingUid());
14845
14846         synchronized (this) {
14847
14848             // iterate across all processes
14849             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14850                 ProcessRecord app = mLruProcesses.get(i);
14851                 if (!allUsers && app.userId != userId) {
14852                     continue;
14853                 }
14854                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14855                     // This one's in trouble, so we'll generate a report for it
14856                     // crashes are higher priority (in case there's a crash *and* an anr)
14857                     ActivityManager.ProcessErrorStateInfo report = null;
14858                     if (app.crashing) {
14859                         report = app.crashingReport;
14860                     } else if (app.notResponding) {
14861                         report = app.notRespondingReport;
14862                     }
14863
14864                     if (report != null) {
14865                         if (errList == null) {
14866                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14867                         }
14868                         errList.add(report);
14869                     } else {
14870                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14871                                 " crashing = " + app.crashing +
14872                                 " notResponding = " + app.notResponding);
14873                     }
14874                 }
14875             }
14876         }
14877
14878         return errList;
14879     }
14880
14881     static int procStateToImportance(int procState, int memAdj,
14882             ActivityManager.RunningAppProcessInfo currApp,
14883             int clientTargetSdk) {
14884         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14885                 procState, clientTargetSdk);
14886         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14887             currApp.lru = memAdj;
14888         } else {
14889             currApp.lru = 0;
14890         }
14891         return imp;
14892     }
14893
14894     private void fillInProcMemInfo(ProcessRecord app,
14895             ActivityManager.RunningAppProcessInfo outInfo,
14896             int clientTargetSdk) {
14897         outInfo.pid = app.pid;
14898         outInfo.uid = app.info.uid;
14899         if (mHeavyWeightProcess == app) {
14900             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14901         }
14902         if (app.persistent) {
14903             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14904         }
14905         if (app.activities.size() > 0) {
14906             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14907         }
14908         outInfo.lastTrimLevel = app.trimMemoryLevel;
14909         int adj = app.curAdj;
14910         int procState = app.curProcState;
14911         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14912         outInfo.importanceReasonCode = app.adjTypeCode;
14913         outInfo.processState = app.curProcState;
14914     }
14915
14916     @Override
14917     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14918         enforceNotIsolatedCaller("getRunningAppProcesses");
14919
14920         final int callingUid = Binder.getCallingUid();
14921         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14922
14923         // Lazy instantiation of list
14924         List<ActivityManager.RunningAppProcessInfo> runList = null;
14925         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14926                 callingUid) == PackageManager.PERMISSION_GRANTED;
14927         final int userId = UserHandle.getUserId(callingUid);
14928         final boolean allUids = isGetTasksAllowed(
14929                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14930
14931         synchronized (this) {
14932             // Iterate across all processes
14933             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14934                 ProcessRecord app = mLruProcesses.get(i);
14935                 if ((!allUsers && app.userId != userId)
14936                         || (!allUids && app.uid != callingUid)) {
14937                     continue;
14938                 }
14939                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14940                     // Generate process state info for running application
14941                     ActivityManager.RunningAppProcessInfo currApp =
14942                         new ActivityManager.RunningAppProcessInfo(app.processName,
14943                                 app.pid, app.getPackageList());
14944                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14945                     if (app.adjSource instanceof ProcessRecord) {
14946                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14947                         currApp.importanceReasonImportance =
14948                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14949                                         app.adjSourceProcState);
14950                     } else if (app.adjSource instanceof ActivityRecord) {
14951                         ActivityRecord r = (ActivityRecord)app.adjSource;
14952                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14953                     }
14954                     if (app.adjTarget instanceof ComponentName) {
14955                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14956                     }
14957                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14958                     //        + " lru=" + currApp.lru);
14959                     if (runList == null) {
14960                         runList = new ArrayList<>();
14961                     }
14962                     runList.add(currApp);
14963                 }
14964             }
14965         }
14966         return runList;
14967     }
14968
14969     @Override
14970     public List<ApplicationInfo> getRunningExternalApplications() {
14971         enforceNotIsolatedCaller("getRunningExternalApplications");
14972         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14973         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14974         if (runningApps != null && runningApps.size() > 0) {
14975             Set<String> extList = new HashSet<String>();
14976             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14977                 if (app.pkgList != null) {
14978                     for (String pkg : app.pkgList) {
14979                         extList.add(pkg);
14980                     }
14981                 }
14982             }
14983             IPackageManager pm = AppGlobals.getPackageManager();
14984             for (String pkg : extList) {
14985                 try {
14986                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14987                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14988                         retList.add(info);
14989                     }
14990                 } catch (RemoteException e) {
14991                 }
14992             }
14993         }
14994         return retList;
14995     }
14996
14997     @Override
14998     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14999         enforceNotIsolatedCaller("getMyMemoryState");
15000
15001         final int callingUid = Binder.getCallingUid();
15002         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15003
15004         synchronized (this) {
15005             ProcessRecord proc;
15006             synchronized (mPidsSelfLocked) {
15007                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15008             }
15009             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15010         }
15011     }
15012
15013     @Override
15014     public int getMemoryTrimLevel() {
15015         enforceNotIsolatedCaller("getMyMemoryState");
15016         synchronized (this) {
15017             return mLastMemoryLevel;
15018         }
15019     }
15020
15021     @Override
15022     public void onShellCommand(FileDescriptor in, FileDescriptor out,
15023             FileDescriptor err, String[] args, ShellCallback callback,
15024             ResultReceiver resultReceiver) {
15025         (new ActivityManagerShellCommand(this, false)).exec(
15026                 this, in, out, err, args, callback, resultReceiver);
15027     }
15028
15029     SleepToken acquireSleepToken(String tag, int displayId) {
15030         synchronized (this) {
15031             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15032             updateSleepIfNeededLocked();
15033             return token;
15034         }
15035     }
15036
15037     @Override
15038     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15039         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15040
15041         boolean dumpAll = false;
15042         boolean dumpClient = false;
15043         boolean dumpCheckin = false;
15044         boolean dumpCheckinFormat = false;
15045         boolean dumpVisibleStacksOnly = false;
15046         boolean dumpFocusedStackOnly = false;
15047         String dumpPackage = null;
15048
15049         int opti = 0;
15050         while (opti < args.length) {
15051             String opt = args[opti];
15052             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15053                 break;
15054             }
15055             opti++;
15056             if ("-a".equals(opt)) {
15057                 dumpAll = true;
15058             } else if ("-c".equals(opt)) {
15059                 dumpClient = true;
15060             } else if ("-v".equals(opt)) {
15061                 dumpVisibleStacksOnly = true;
15062             } else if ("-f".equals(opt)) {
15063                 dumpFocusedStackOnly = true;
15064             } else if ("-p".equals(opt)) {
15065                 if (opti < args.length) {
15066                     dumpPackage = args[opti];
15067                     opti++;
15068                 } else {
15069                     pw.println("Error: -p option requires package argument");
15070                     return;
15071                 }
15072                 dumpClient = true;
15073             } else if ("--checkin".equals(opt)) {
15074                 dumpCheckin = dumpCheckinFormat = true;
15075             } else if ("-C".equals(opt)) {
15076                 dumpCheckinFormat = true;
15077             } else if ("-h".equals(opt)) {
15078                 ActivityManagerShellCommand.dumpHelp(pw, true);
15079                 return;
15080             } else {
15081                 pw.println("Unknown argument: " + opt + "; use -h for help");
15082             }
15083         }
15084
15085         long origId = Binder.clearCallingIdentity();
15086         boolean more = false;
15087         // Is the caller requesting to dump a particular piece of data?
15088         if (opti < args.length) {
15089             String cmd = args[opti];
15090             opti++;
15091             if ("activities".equals(cmd) || "a".equals(cmd)) {
15092                 synchronized (this) {
15093                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15094                 }
15095             } else if ("lastanr".equals(cmd)) {
15096                 synchronized (this) {
15097                     dumpLastANRLocked(pw);
15098                 }
15099             } else if ("starter".equals(cmd)) {
15100                 synchronized (this) {
15101                     dumpActivityStarterLocked(pw, dumpPackage);
15102                 }
15103             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15104                 synchronized (this) {
15105                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15106                 }
15107             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15108                 String[] newArgs;
15109                 String name;
15110                 if (opti >= args.length) {
15111                     name = null;
15112                     newArgs = EMPTY_STRING_ARRAY;
15113                 } else {
15114                     dumpPackage = args[opti];
15115                     opti++;
15116                     newArgs = new String[args.length - opti];
15117                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15118                             args.length - opti);
15119                 }
15120                 synchronized (this) {
15121                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15122                 }
15123             } else if ("broadcast-stats".equals(cmd)) {
15124                 String[] newArgs;
15125                 String name;
15126                 if (opti >= args.length) {
15127                     name = null;
15128                     newArgs = EMPTY_STRING_ARRAY;
15129                 } else {
15130                     dumpPackage = args[opti];
15131                     opti++;
15132                     newArgs = new String[args.length - opti];
15133                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15134                             args.length - opti);
15135                 }
15136                 synchronized (this) {
15137                     if (dumpCheckinFormat) {
15138                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15139                                 dumpPackage);
15140                     } else {
15141                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15142                     }
15143                 }
15144             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15145                 String[] newArgs;
15146                 String name;
15147                 if (opti >= args.length) {
15148                     name = null;
15149                     newArgs = EMPTY_STRING_ARRAY;
15150                 } else {
15151                     dumpPackage = args[opti];
15152                     opti++;
15153                     newArgs = new String[args.length - opti];
15154                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15155                             args.length - opti);
15156                 }
15157                 synchronized (this) {
15158                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15159                 }
15160             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15161                 String[] newArgs;
15162                 String name;
15163                 if (opti >= args.length) {
15164                     name = null;
15165                     newArgs = EMPTY_STRING_ARRAY;
15166                 } else {
15167                     dumpPackage = args[opti];
15168                     opti++;
15169                     newArgs = new String[args.length - opti];
15170                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15171                             args.length - opti);
15172                 }
15173                 synchronized (this) {
15174                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15175                 }
15176             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15177                 synchronized (this) {
15178                     dumpOomLocked(fd, pw, args, opti, true);
15179                 }
15180             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15181                 synchronized (this) {
15182                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15183                 }
15184             } else if ("provider".equals(cmd)) {
15185                 String[] newArgs;
15186                 String name;
15187                 if (opti >= args.length) {
15188                     name = null;
15189                     newArgs = EMPTY_STRING_ARRAY;
15190                 } else {
15191                     name = args[opti];
15192                     opti++;
15193                     newArgs = new String[args.length - opti];
15194                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15195                 }
15196                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15197                     pw.println("No providers match: " + name);
15198                     pw.println("Use -h for help.");
15199                 }
15200             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15201                 synchronized (this) {
15202                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15203                 }
15204             } else if ("service".equals(cmd)) {
15205                 String[] newArgs;
15206                 String name;
15207                 if (opti >= args.length) {
15208                     name = null;
15209                     newArgs = EMPTY_STRING_ARRAY;
15210                 } else {
15211                     name = args[opti];
15212                     opti++;
15213                     newArgs = new String[args.length - opti];
15214                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15215                             args.length - opti);
15216                 }
15217                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15218                     pw.println("No services match: " + name);
15219                     pw.println("Use -h for help.");
15220                 }
15221             } else if ("package".equals(cmd)) {
15222                 String[] newArgs;
15223                 if (opti >= args.length) {
15224                     pw.println("package: no package name specified");
15225                     pw.println("Use -h for help.");
15226                 } else {
15227                     dumpPackage = args[opti];
15228                     opti++;
15229                     newArgs = new String[args.length - opti];
15230                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15231                             args.length - opti);
15232                     args = newArgs;
15233                     opti = 0;
15234                     more = true;
15235                 }
15236             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15237                 synchronized (this) {
15238                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15239                 }
15240             } else if ("settings".equals(cmd)) {
15241                 synchronized (this) {
15242                     mConstants.dump(pw);
15243                 }
15244             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15245                 if (dumpClient) {
15246                     ActiveServices.ServiceDumper dumper;
15247                     synchronized (this) {
15248                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15249                                 dumpPackage);
15250                     }
15251                     dumper.dumpWithClient();
15252                 } else {
15253                     synchronized (this) {
15254                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15255                                 dumpPackage).dumpLocked();
15256                     }
15257                 }
15258             } else if ("locks".equals(cmd)) {
15259                 LockGuard.dump(fd, pw, args);
15260             } else {
15261                 // Dumping a single activity?
15262                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15263                         dumpFocusedStackOnly)) {
15264                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15265                     int res = shell.exec(this, null, fd, null, args, null,
15266                             new ResultReceiver(null));
15267                     if (res < 0) {
15268                         pw.println("Bad activity command, or no activities match: " + cmd);
15269                         pw.println("Use -h for help.");
15270                     }
15271                 }
15272             }
15273             if (!more) {
15274                 Binder.restoreCallingIdentity(origId);
15275                 return;
15276             }
15277         }
15278
15279         // No piece of data specified, dump everything.
15280         if (dumpCheckinFormat) {
15281             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15282         } else if (dumpClient) {
15283             ActiveServices.ServiceDumper sdumper;
15284             synchronized (this) {
15285                 mConstants.dump(pw);
15286                 pw.println();
15287                 if (dumpAll) {
15288                     pw.println("-------------------------------------------------------------------------------");
15289                 }
15290                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15291                 pw.println();
15292                 if (dumpAll) {
15293                     pw.println("-------------------------------------------------------------------------------");
15294                 }
15295                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15296                 pw.println();
15297                 if (dumpAll) {
15298                     pw.println("-------------------------------------------------------------------------------");
15299                 }
15300                 if (dumpAll || dumpPackage != null) {
15301                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15302                     pw.println();
15303                     if (dumpAll) {
15304                         pw.println("-------------------------------------------------------------------------------");
15305                     }
15306                 }
15307                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15308                 pw.println();
15309                 if (dumpAll) {
15310                     pw.println("-------------------------------------------------------------------------------");
15311                 }
15312                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15313                 pw.println();
15314                 if (dumpAll) {
15315                     pw.println("-------------------------------------------------------------------------------");
15316                 }
15317                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15318                         dumpPackage);
15319             }
15320             sdumper.dumpWithClient();
15321             pw.println();
15322             synchronized (this) {
15323                 if (dumpAll) {
15324                     pw.println("-------------------------------------------------------------------------------");
15325                 }
15326                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15327                 pw.println();
15328                 if (dumpAll) {
15329                     pw.println("-------------------------------------------------------------------------------");
15330                 }
15331                 dumpLastANRLocked(pw);
15332                 pw.println();
15333                 if (dumpAll) {
15334                     pw.println("-------------------------------------------------------------------------------");
15335                 }
15336                 dumpActivityStarterLocked(pw, dumpPackage);
15337                 pw.println();
15338                 if (dumpAll) {
15339                     pw.println("-------------------------------------------------------------------------------");
15340                 }
15341                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15342                 if (mAssociations.size() > 0) {
15343                     pw.println();
15344                     if (dumpAll) {
15345                         pw.println("-------------------------------------------------------------------------------");
15346                     }
15347                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15348                 }
15349                 pw.println();
15350                 if (dumpAll) {
15351                     pw.println("-------------------------------------------------------------------------------");
15352                 }
15353                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15354             }
15355
15356         } else {
15357             synchronized (this) {
15358                 mConstants.dump(pw);
15359                 pw.println();
15360                 if (dumpAll) {
15361                     pw.println("-------------------------------------------------------------------------------");
15362                 }
15363                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15364                 pw.println();
15365                 if (dumpAll) {
15366                     pw.println("-------------------------------------------------------------------------------");
15367                 }
15368                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15369                 pw.println();
15370                 if (dumpAll) {
15371                     pw.println("-------------------------------------------------------------------------------");
15372                 }
15373                 if (dumpAll || dumpPackage != null) {
15374                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15375                     pw.println();
15376                     if (dumpAll) {
15377                         pw.println("-------------------------------------------------------------------------------");
15378                     }
15379                 }
15380                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15381                 pw.println();
15382                 if (dumpAll) {
15383                     pw.println("-------------------------------------------------------------------------------");
15384                 }
15385                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15386                 pw.println();
15387                 if (dumpAll) {
15388                     pw.println("-------------------------------------------------------------------------------");
15389                 }
15390                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15391                         .dumpLocked();
15392                 pw.println();
15393                 if (dumpAll) {
15394                     pw.println("-------------------------------------------------------------------------------");
15395                 }
15396                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15397                 pw.println();
15398                 if (dumpAll) {
15399                     pw.println("-------------------------------------------------------------------------------");
15400                 }
15401                 dumpLastANRLocked(pw);
15402                 pw.println();
15403                 if (dumpAll) {
15404                     pw.println("-------------------------------------------------------------------------------");
15405                 }
15406                 dumpActivityStarterLocked(pw, dumpPackage);
15407                 pw.println();
15408                 if (dumpAll) {
15409                     pw.println("-------------------------------------------------------------------------------");
15410                 }
15411                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15412                 if (mAssociations.size() > 0) {
15413                     pw.println();
15414                     if (dumpAll) {
15415                         pw.println("-------------------------------------------------------------------------------");
15416                     }
15417                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15418                 }
15419                 pw.println();
15420                 if (dumpAll) {
15421                     pw.println("-------------------------------------------------------------------------------");
15422                 }
15423                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15424             }
15425         }
15426         Binder.restoreCallingIdentity(origId);
15427     }
15428
15429     private void dumpLastANRLocked(PrintWriter pw) {
15430         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15431         if (mLastANRState == null) {
15432             pw.println("  <no ANR has occurred since boot>");
15433         } else {
15434             pw.println(mLastANRState);
15435         }
15436     }
15437
15438     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15439         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15440         mActivityStarter.dump(pw, "", dumpPackage);
15441     }
15442
15443     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15444             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15445         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15446                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15447     }
15448
15449     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15450             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15451         pw.println(header);
15452
15453         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15454                 dumpPackage);
15455         boolean needSep = printedAnything;
15456
15457         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15458                 mStackSupervisor.getResumedActivityLocked(),
15459                 dumpPackage, needSep, "  ResumedActivity: ");
15460         if (printed) {
15461             printedAnything = true;
15462             needSep = false;
15463         }
15464
15465         if (dumpPackage == null) {
15466             if (needSep) {
15467                 pw.println();
15468             }
15469             printedAnything = true;
15470             mStackSupervisor.dump(pw, "  ");
15471         }
15472
15473         if (!printedAnything) {
15474             pw.println("  (nothing)");
15475         }
15476     }
15477
15478     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15479             int opti, boolean dumpAll, String dumpPackage) {
15480         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15481
15482         boolean printedAnything = false;
15483
15484         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15485             boolean printedHeader = false;
15486
15487             final int N = mRecentTasks.size();
15488             for (int i=0; i<N; i++) {
15489                 TaskRecord tr = mRecentTasks.get(i);
15490                 if (dumpPackage != null) {
15491                     if (tr.realActivity == null ||
15492                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15493                         continue;
15494                     }
15495                 }
15496                 if (!printedHeader) {
15497                     pw.println("  Recent tasks:");
15498                     printedHeader = true;
15499                     printedAnything = true;
15500                 }
15501                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15502                         pw.println(tr);
15503                 if (dumpAll) {
15504                     mRecentTasks.get(i).dump(pw, "    ");
15505                 }
15506             }
15507         }
15508
15509         if (!printedAnything) {
15510             pw.println("  (nothing)");
15511         }
15512     }
15513
15514     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15515             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15516         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15517
15518         int dumpUid = 0;
15519         if (dumpPackage != null) {
15520             IPackageManager pm = AppGlobals.getPackageManager();
15521             try {
15522                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15523             } catch (RemoteException e) {
15524             }
15525         }
15526
15527         boolean printedAnything = false;
15528
15529         final long now = SystemClock.uptimeMillis();
15530
15531         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15532             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15533                     = mAssociations.valueAt(i1);
15534             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15535                 SparseArray<ArrayMap<String, Association>> sourceUids
15536                         = targetComponents.valueAt(i2);
15537                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15538                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15539                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15540                         Association ass = sourceProcesses.valueAt(i4);
15541                         if (dumpPackage != null) {
15542                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15543                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15544                                 continue;
15545                             }
15546                         }
15547                         printedAnything = true;
15548                         pw.print("  ");
15549                         pw.print(ass.mTargetProcess);
15550                         pw.print("/");
15551                         UserHandle.formatUid(pw, ass.mTargetUid);
15552                         pw.print(" <- ");
15553                         pw.print(ass.mSourceProcess);
15554                         pw.print("/");
15555                         UserHandle.formatUid(pw, ass.mSourceUid);
15556                         pw.println();
15557                         pw.print("    via ");
15558                         pw.print(ass.mTargetComponent.flattenToShortString());
15559                         pw.println();
15560                         pw.print("    ");
15561                         long dur = ass.mTime;
15562                         if (ass.mNesting > 0) {
15563                             dur += now - ass.mStartTime;
15564                         }
15565                         TimeUtils.formatDuration(dur, pw);
15566                         pw.print(" (");
15567                         pw.print(ass.mCount);
15568                         pw.print(" times)");
15569                         pw.print("  ");
15570                         for (int i=0; i<ass.mStateTimes.length; i++) {
15571                             long amt = ass.mStateTimes[i];
15572                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15573                                 amt += now - ass.mLastStateUptime;
15574                             }
15575                             if (amt != 0) {
15576                                 pw.print(" ");
15577                                 pw.print(ProcessList.makeProcStateString(
15578                                             i + ActivityManager.MIN_PROCESS_STATE));
15579                                 pw.print("=");
15580                                 TimeUtils.formatDuration(amt, pw);
15581                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15582                                     pw.print("*");
15583                                 }
15584                             }
15585                         }
15586                         pw.println();
15587                         if (ass.mNesting > 0) {
15588                             pw.print("    Currently active: ");
15589                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15590                             pw.println();
15591                         }
15592                     }
15593                 }
15594             }
15595
15596         }
15597
15598         if (!printedAnything) {
15599             pw.println("  (nothing)");
15600         }
15601     }
15602
15603     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15604             String header, boolean needSep) {
15605         boolean printed = false;
15606         int whichAppId = -1;
15607         if (dumpPackage != null) {
15608             try {
15609                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15610                         dumpPackage, 0);
15611                 whichAppId = UserHandle.getAppId(info.uid);
15612             } catch (NameNotFoundException e) {
15613                 e.printStackTrace();
15614             }
15615         }
15616         for (int i=0; i<uids.size(); i++) {
15617             UidRecord uidRec = uids.valueAt(i);
15618             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15619                 continue;
15620             }
15621             if (!printed) {
15622                 printed = true;
15623                 if (needSep) {
15624                     pw.println();
15625                 }
15626                 pw.print("  ");
15627                 pw.println(header);
15628                 needSep = true;
15629             }
15630             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15631             pw.print(": "); pw.println(uidRec);
15632         }
15633         return printed;
15634     }
15635
15636     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15637             int opti, boolean dumpAll, String dumpPackage) {
15638         boolean needSep = false;
15639         boolean printedAnything = false;
15640         int numPers = 0;
15641
15642         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15643
15644         if (dumpAll) {
15645             final int NP = mProcessNames.getMap().size();
15646             for (int ip=0; ip<NP; ip++) {
15647                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15648                 final int NA = procs.size();
15649                 for (int ia=0; ia<NA; ia++) {
15650                     ProcessRecord r = procs.valueAt(ia);
15651                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15652                         continue;
15653                     }
15654                     if (!needSep) {
15655                         pw.println("  All known processes:");
15656                         needSep = true;
15657                         printedAnything = true;
15658                     }
15659                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15660                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15661                         pw.print(" "); pw.println(r);
15662                     r.dump(pw, "    ");
15663                     if (r.persistent) {
15664                         numPers++;
15665                     }
15666                 }
15667             }
15668         }
15669
15670         if (mIsolatedProcesses.size() > 0) {
15671             boolean printed = false;
15672             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15673                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15674                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15675                     continue;
15676                 }
15677                 if (!printed) {
15678                     if (needSep) {
15679                         pw.println();
15680                     }
15681                     pw.println("  Isolated process list (sorted by uid):");
15682                     printedAnything = true;
15683                     printed = true;
15684                     needSep = true;
15685                 }
15686                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15687                 pw.println(r);
15688             }
15689         }
15690
15691         if (mActiveInstrumentation.size() > 0) {
15692             boolean printed = false;
15693             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15694                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15695                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15696                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15697                     continue;
15698                 }
15699                 if (!printed) {
15700                     if (needSep) {
15701                         pw.println();
15702                     }
15703                     pw.println("  Active instrumentation:");
15704                     printedAnything = true;
15705                     printed = true;
15706                     needSep = true;
15707                 }
15708                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15709                 pw.println(ai);
15710                 ai.dump(pw, "      ");
15711             }
15712         }
15713
15714         if (mActiveUids.size() > 0) {
15715             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15716                 printedAnything = needSep = true;
15717             }
15718         }
15719         if (dumpAll) {
15720             if (mValidateUids.size() > 0) {
15721                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15722                     printedAnything = needSep = true;
15723                 }
15724             }
15725         }
15726
15727         if (mLruProcesses.size() > 0) {
15728             if (needSep) {
15729                 pw.println();
15730             }
15731             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15732                     pw.print(" total, non-act at ");
15733                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15734                     pw.print(", non-svc at ");
15735                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15736                     pw.println("):");
15737             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15738             needSep = true;
15739             printedAnything = true;
15740         }
15741
15742         if (dumpAll || dumpPackage != null) {
15743             synchronized (mPidsSelfLocked) {
15744                 boolean printed = false;
15745                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15746                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15747                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15748                         continue;
15749                     }
15750                     if (!printed) {
15751                         if (needSep) pw.println();
15752                         needSep = true;
15753                         pw.println("  PID mappings:");
15754                         printed = true;
15755                         printedAnything = true;
15756                     }
15757                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15758                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15759                 }
15760             }
15761         }
15762
15763         if (mImportantProcesses.size() > 0) {
15764             synchronized (mPidsSelfLocked) {
15765                 boolean printed = false;
15766                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15767                     ProcessRecord r = mPidsSelfLocked.get(
15768                             mImportantProcesses.valueAt(i).pid);
15769                     if (dumpPackage != null && (r == null
15770                             || !r.pkgList.containsKey(dumpPackage))) {
15771                         continue;
15772                     }
15773                     if (!printed) {
15774                         if (needSep) pw.println();
15775                         needSep = true;
15776                         pw.println("  Foreground Processes:");
15777                         printed = true;
15778                         printedAnything = true;
15779                     }
15780                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15781                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15782                 }
15783             }
15784         }
15785
15786         if (mPersistentStartingProcesses.size() > 0) {
15787             if (needSep) pw.println();
15788             needSep = true;
15789             printedAnything = true;
15790             pw.println("  Persisent processes that are starting:");
15791             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15792                     "Starting Norm", "Restarting PERS", dumpPackage);
15793         }
15794
15795         if (mRemovedProcesses.size() > 0) {
15796             if (needSep) pw.println();
15797             needSep = true;
15798             printedAnything = true;
15799             pw.println("  Processes that are being removed:");
15800             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15801                     "Removed Norm", "Removed PERS", dumpPackage);
15802         }
15803
15804         if (mProcessesOnHold.size() > 0) {
15805             if (needSep) pw.println();
15806             needSep = true;
15807             printedAnything = true;
15808             pw.println("  Processes that are on old until the system is ready:");
15809             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15810                     "OnHold Norm", "OnHold PERS", dumpPackage);
15811         }
15812
15813         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15814
15815         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15816         if (needSep) {
15817             printedAnything = true;
15818         }
15819
15820         if (dumpPackage == null) {
15821             pw.println();
15822             needSep = false;
15823             mUserController.dump(pw, dumpAll);
15824         }
15825         if (mHomeProcess != null && (dumpPackage == null
15826                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15827             if (needSep) {
15828                 pw.println();
15829                 needSep = false;
15830             }
15831             pw.println("  mHomeProcess: " + mHomeProcess);
15832         }
15833         if (mPreviousProcess != null && (dumpPackage == null
15834                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15835             if (needSep) {
15836                 pw.println();
15837                 needSep = false;
15838             }
15839             pw.println("  mPreviousProcess: " + mPreviousProcess);
15840         }
15841         if (dumpAll) {
15842             StringBuilder sb = new StringBuilder(128);
15843             sb.append("  mPreviousProcessVisibleTime: ");
15844             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15845             pw.println(sb);
15846         }
15847         if (mHeavyWeightProcess != null && (dumpPackage == null
15848                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15849             if (needSep) {
15850                 pw.println();
15851                 needSep = false;
15852             }
15853             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15854         }
15855         if (dumpPackage == null) {
15856             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15857             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15858         }
15859         if (dumpAll) {
15860             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15861             if (mCompatModePackages.getPackages().size() > 0) {
15862                 boolean printed = false;
15863                 for (Map.Entry<String, Integer> entry
15864                         : mCompatModePackages.getPackages().entrySet()) {
15865                     String pkg = entry.getKey();
15866                     int mode = entry.getValue();
15867                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15868                         continue;
15869                     }
15870                     if (!printed) {
15871                         pw.println("  mScreenCompatPackages:");
15872                         printed = true;
15873                     }
15874                     pw.print("    "); pw.print(pkg); pw.print(": ");
15875                             pw.print(mode); pw.println();
15876                 }
15877             }
15878             final int NI = mUidObservers.getRegisteredCallbackCount();
15879             boolean printed = false;
15880             for (int i=0; i<NI; i++) {
15881                 final UidObserverRegistration reg = (UidObserverRegistration)
15882                         mUidObservers.getRegisteredCallbackCookie(i);
15883                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15884                     if (!printed) {
15885                         pw.println("  mUidObservers:");
15886                         printed = true;
15887                     }
15888                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15889                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15890                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15891                         pw.print(" IDLE");
15892                     }
15893                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15894                         pw.print(" ACT" );
15895                     }
15896                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15897                         pw.print(" GONE");
15898                     }
15899                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15900                         pw.print(" STATE");
15901                         pw.print(" (cut="); pw.print(reg.cutpoint);
15902                         pw.print(")");
15903                     }
15904                     pw.println();
15905                     if (reg.lastProcStates != null) {
15906                         final int NJ = reg.lastProcStates.size();
15907                         for (int j=0; j<NJ; j++) {
15908                             pw.print("      Last ");
15909                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15910                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15911                         }
15912                     }
15913                 }
15914             }
15915             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15916             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15917             if (mPendingTempWhitelist.size() > 0) {
15918                 pw.println("  mPendingTempWhitelist:");
15919                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15920                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15921                     pw.print("    ");
15922                     UserHandle.formatUid(pw, ptw.targetUid);
15923                     pw.print(": ");
15924                     TimeUtils.formatDuration(ptw.duration, pw);
15925                     pw.print(" ");
15926                     pw.println(ptw.tag);
15927                 }
15928             }
15929         }
15930         if (dumpPackage == null) {
15931             pw.println("  mWakefulness="
15932                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15933             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15934             pw.println("  mSleeping=" + mSleeping);
15935             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15936             if (mRunningVoice != null) {
15937                 pw.println("  mRunningVoice=" + mRunningVoice);
15938                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15939             }
15940         }
15941         pw.println("  mVrController=" + mVrController);
15942         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15943                 || mOrigWaitForDebugger) {
15944             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15945                     || dumpPackage.equals(mOrigDebugApp)) {
15946                 if (needSep) {
15947                     pw.println();
15948                     needSep = false;
15949                 }
15950                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15951                         + " mDebugTransient=" + mDebugTransient
15952                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15953             }
15954         }
15955         if (mCurAppTimeTracker != null) {
15956             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15957         }
15958         if (mMemWatchProcesses.getMap().size() > 0) {
15959             pw.println("  Mem watch processes:");
15960             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15961                     = mMemWatchProcesses.getMap();
15962             for (int i=0; i<procs.size(); i++) {
15963                 final String proc = procs.keyAt(i);
15964                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15965                 for (int j=0; j<uids.size(); j++) {
15966                     if (needSep) {
15967                         pw.println();
15968                         needSep = false;
15969                     }
15970                     StringBuilder sb = new StringBuilder();
15971                     sb.append("    ").append(proc).append('/');
15972                     UserHandle.formatUid(sb, uids.keyAt(j));
15973                     Pair<Long, String> val = uids.valueAt(j);
15974                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15975                     if (val.second != null) {
15976                         sb.append(", report to ").append(val.second);
15977                     }
15978                     pw.println(sb.toString());
15979                 }
15980             }
15981             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15982             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15983             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15984                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15985         }
15986         if (mTrackAllocationApp != null) {
15987             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15988                 if (needSep) {
15989                     pw.println();
15990                     needSep = false;
15991                 }
15992                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15993             }
15994         }
15995         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15996                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15997             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15998                 if (needSep) {
15999                     pw.println();
16000                     needSep = false;
16001                 }
16002                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16003                 if (mProfilerInfo != null) {
16004                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16005                             mProfilerInfo.profileFd);
16006                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16007                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16008                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16009                     pw.println("  mProfileType=" + mProfileType);
16010                 }
16011             }
16012         }
16013         if (mNativeDebuggingApp != null) {
16014             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16015                 if (needSep) {
16016                     pw.println();
16017                     needSep = false;
16018                 }
16019                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16020             }
16021         }
16022         if (dumpPackage == null) {
16023             if (mAlwaysFinishActivities) {
16024                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16025             }
16026             if (mController != null) {
16027                 pw.println("  mController=" + mController
16028                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16029             }
16030             if (dumpAll) {
16031                 pw.println("  Total persistent processes: " + numPers);
16032                 pw.println("  mProcessesReady=" + mProcessesReady
16033                         + " mSystemReady=" + mSystemReady
16034                         + " mBooted=" + mBooted
16035                         + " mFactoryTest=" + mFactoryTest);
16036                 pw.println("  mBooting=" + mBooting
16037                         + " mCallFinishBooting=" + mCallFinishBooting
16038                         + " mBootAnimationComplete=" + mBootAnimationComplete);
16039                 pw.print("  mLastPowerCheckUptime=");
16040                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16041                         pw.println("");
16042                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16043                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16044                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16045                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16046                         + " (" + mLruProcesses.size() + " total)"
16047                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16048                         + " mNumServiceProcs=" + mNumServiceProcs
16049                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16050                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16051                         + " mLastMemoryLevel=" + mLastMemoryLevel
16052                         + " mLastNumProcesses=" + mLastNumProcesses);
16053                 long now = SystemClock.uptimeMillis();
16054                 pw.print("  mLastIdleTime=");
16055                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
16056                         pw.print(" mLowRamSinceLastIdle=");
16057                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16058                         pw.println();
16059             }
16060         }
16061
16062         if (!printedAnything) {
16063             pw.println("  (nothing)");
16064         }
16065     }
16066
16067     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16068             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16069         if (mProcessesToGc.size() > 0) {
16070             boolean printed = false;
16071             long now = SystemClock.uptimeMillis();
16072             for (int i=0; i<mProcessesToGc.size(); i++) {
16073                 ProcessRecord proc = mProcessesToGc.get(i);
16074                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16075                     continue;
16076                 }
16077                 if (!printed) {
16078                     if (needSep) pw.println();
16079                     needSep = true;
16080                     pw.println("  Processes that are waiting to GC:");
16081                     printed = true;
16082                 }
16083                 pw.print("    Process "); pw.println(proc);
16084                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16085                         pw.print(", last gced=");
16086                         pw.print(now-proc.lastRequestedGc);
16087                         pw.print(" ms ago, last lowMem=");
16088                         pw.print(now-proc.lastLowMemory);
16089                         pw.println(" ms ago");
16090
16091             }
16092         }
16093         return needSep;
16094     }
16095
16096     void printOomLevel(PrintWriter pw, String name, int adj) {
16097         pw.print("    ");
16098         if (adj >= 0) {
16099             pw.print(' ');
16100             if (adj < 10) pw.print(' ');
16101         } else {
16102             if (adj > -10) pw.print(' ');
16103         }
16104         pw.print(adj);
16105         pw.print(": ");
16106         pw.print(name);
16107         pw.print(" (");
16108         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16109         pw.println(")");
16110     }
16111
16112     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16113             int opti, boolean dumpAll) {
16114         boolean needSep = false;
16115
16116         if (mLruProcesses.size() > 0) {
16117             if (needSep) pw.println();
16118             needSep = true;
16119             pw.println("  OOM levels:");
16120             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16121             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16122             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16123             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16124             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16125             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16126             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16127             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16128             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16129             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16130             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16131             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16132             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16133             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16134
16135             if (needSep) pw.println();
16136             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16137                     pw.print(" total, non-act at ");
16138                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16139                     pw.print(", non-svc at ");
16140                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16141                     pw.println("):");
16142             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16143             needSep = true;
16144         }
16145
16146         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16147
16148         pw.println();
16149         pw.println("  mHomeProcess: " + mHomeProcess);
16150         pw.println("  mPreviousProcess: " + mPreviousProcess);
16151         if (mHeavyWeightProcess != null) {
16152             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16153         }
16154
16155         return true;
16156     }
16157
16158     /**
16159      * There are three ways to call this:
16160      *  - no provider specified: dump all the providers
16161      *  - a flattened component name that matched an existing provider was specified as the
16162      *    first arg: dump that one provider
16163      *  - the first arg isn't the flattened component name of an existing provider:
16164      *    dump all providers whose component contains the first arg as a substring
16165      */
16166     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16167             int opti, boolean dumpAll) {
16168         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16169     }
16170
16171     static class ItemMatcher {
16172         ArrayList<ComponentName> components;
16173         ArrayList<String> strings;
16174         ArrayList<Integer> objects;
16175         boolean all;
16176
16177         ItemMatcher() {
16178             all = true;
16179         }
16180
16181         void build(String name) {
16182             ComponentName componentName = ComponentName.unflattenFromString(name);
16183             if (componentName != null) {
16184                 if (components == null) {
16185                     components = new ArrayList<ComponentName>();
16186                 }
16187                 components.add(componentName);
16188                 all = false;
16189             } else {
16190                 int objectId = 0;
16191                 // Not a '/' separated full component name; maybe an object ID?
16192                 try {
16193                     objectId = Integer.parseInt(name, 16);
16194                     if (objects == null) {
16195                         objects = new ArrayList<Integer>();
16196                     }
16197                     objects.add(objectId);
16198                     all = false;
16199                 } catch (RuntimeException e) {
16200                     // Not an integer; just do string match.
16201                     if (strings == null) {
16202                         strings = new ArrayList<String>();
16203                     }
16204                     strings.add(name);
16205                     all = false;
16206                 }
16207             }
16208         }
16209
16210         int build(String[] args, int opti) {
16211             for (; opti<args.length; opti++) {
16212                 String name = args[opti];
16213                 if ("--".equals(name)) {
16214                     return opti+1;
16215                 }
16216                 build(name);
16217             }
16218             return opti;
16219         }
16220
16221         boolean match(Object object, ComponentName comp) {
16222             if (all) {
16223                 return true;
16224             }
16225             if (components != null) {
16226                 for (int i=0; i<components.size(); i++) {
16227                     if (components.get(i).equals(comp)) {
16228                         return true;
16229                     }
16230                 }
16231             }
16232             if (objects != null) {
16233                 for (int i=0; i<objects.size(); i++) {
16234                     if (System.identityHashCode(object) == objects.get(i)) {
16235                         return true;
16236                     }
16237                 }
16238             }
16239             if (strings != null) {
16240                 String flat = comp.flattenToString();
16241                 for (int i=0; i<strings.size(); i++) {
16242                     if (flat.contains(strings.get(i))) {
16243                         return true;
16244                     }
16245                 }
16246             }
16247             return false;
16248         }
16249     }
16250
16251     /**
16252      * There are three things that cmd can be:
16253      *  - a flattened component name that matches an existing activity
16254      *  - the cmd arg isn't the flattened component name of an existing activity:
16255      *    dump all activity whose component contains the cmd as a substring
16256      *  - A hex number of the ActivityRecord object instance.
16257      *
16258      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16259      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16260      */
16261     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16262             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16263         ArrayList<ActivityRecord> activities;
16264
16265         synchronized (this) {
16266             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16267                     dumpFocusedStackOnly);
16268         }
16269
16270         if (activities.size() <= 0) {
16271             return false;
16272         }
16273
16274         String[] newArgs = new String[args.length - opti];
16275         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16276
16277         TaskRecord lastTask = null;
16278         boolean needSep = false;
16279         for (int i=activities.size()-1; i>=0; i--) {
16280             ActivityRecord r = activities.get(i);
16281             if (needSep) {
16282                 pw.println();
16283             }
16284             needSep = true;
16285             synchronized (this) {
16286                 final TaskRecord task = r.getTask();
16287                 if (lastTask != task) {
16288                     lastTask = task;
16289                     pw.print("TASK "); pw.print(lastTask.affinity);
16290                             pw.print(" id="); pw.print(lastTask.taskId);
16291                             pw.print(" userId="); pw.println(lastTask.userId);
16292                     if (dumpAll) {
16293                         lastTask.dump(pw, "  ");
16294                     }
16295                 }
16296             }
16297             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16298         }
16299         return true;
16300     }
16301
16302     /**
16303      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16304      * there is a thread associated with the activity.
16305      */
16306     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16307             final ActivityRecord r, String[] args, boolean dumpAll) {
16308         String innerPrefix = prefix + "  ";
16309         synchronized (this) {
16310             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16311                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16312                     pw.print(" pid=");
16313                     if (r.app != null) pw.println(r.app.pid);
16314                     else pw.println("(not running)");
16315             if (dumpAll) {
16316                 r.dump(pw, innerPrefix);
16317             }
16318         }
16319         if (r.app != null && r.app.thread != null) {
16320             // flush anything that is already in the PrintWriter since the thread is going
16321             // to write to the file descriptor directly
16322             pw.flush();
16323             try {
16324                 TransferPipe tp = new TransferPipe();
16325                 try {
16326                     r.app.thread.dumpActivity(tp.getWriteFd(),
16327                             r.appToken, innerPrefix, args);
16328                     tp.go(fd);
16329                 } finally {
16330                     tp.kill();
16331                 }
16332             } catch (IOException e) {
16333                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16334             } catch (RemoteException e) {
16335                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16336             }
16337         }
16338     }
16339
16340     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16341             int opti, boolean dumpAll, String dumpPackage) {
16342         boolean needSep = false;
16343         boolean onlyHistory = false;
16344         boolean printedAnything = false;
16345
16346         if ("history".equals(dumpPackage)) {
16347             if (opti < args.length && "-s".equals(args[opti])) {
16348                 dumpAll = false;
16349             }
16350             onlyHistory = true;
16351             dumpPackage = null;
16352         }
16353
16354         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16355         if (!onlyHistory && dumpAll) {
16356             if (mRegisteredReceivers.size() > 0) {
16357                 boolean printed = false;
16358                 Iterator it = mRegisteredReceivers.values().iterator();
16359                 while (it.hasNext()) {
16360                     ReceiverList r = (ReceiverList)it.next();
16361                     if (dumpPackage != null && (r.app == null ||
16362                             !dumpPackage.equals(r.app.info.packageName))) {
16363                         continue;
16364                     }
16365                     if (!printed) {
16366                         pw.println("  Registered Receivers:");
16367                         needSep = true;
16368                         printed = true;
16369                         printedAnything = true;
16370                     }
16371                     pw.print("  * "); pw.println(r);
16372                     r.dump(pw, "    ");
16373                 }
16374             }
16375
16376             if (mReceiverResolver.dump(pw, needSep ?
16377                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16378                     "    ", dumpPackage, false, false)) {
16379                 needSep = true;
16380                 printedAnything = true;
16381             }
16382         }
16383
16384         for (BroadcastQueue q : mBroadcastQueues) {
16385             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16386             printedAnything |= needSep;
16387         }
16388
16389         needSep = true;
16390
16391         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16392             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16393                 if (needSep) {
16394                     pw.println();
16395                 }
16396                 needSep = true;
16397                 printedAnything = true;
16398                 pw.print("  Sticky broadcasts for user ");
16399                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16400                 StringBuilder sb = new StringBuilder(128);
16401                 for (Map.Entry<String, ArrayList<Intent>> ent
16402                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16403                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16404                     if (dumpAll) {
16405                         pw.println(":");
16406                         ArrayList<Intent> intents = ent.getValue();
16407                         final int N = intents.size();
16408                         for (int i=0; i<N; i++) {
16409                             sb.setLength(0);
16410                             sb.append("    Intent: ");
16411                             intents.get(i).toShortString(sb, false, true, false, false);
16412                             pw.println(sb.toString());
16413                             Bundle bundle = intents.get(i).getExtras();
16414                             if (bundle != null) {
16415                                 pw.print("      ");
16416                                 pw.println(bundle.toString());
16417                             }
16418                         }
16419                     } else {
16420                         pw.println("");
16421                     }
16422                 }
16423             }
16424         }
16425
16426         if (!onlyHistory && dumpAll) {
16427             pw.println();
16428             for (BroadcastQueue queue : mBroadcastQueues) {
16429                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16430                         + queue.mBroadcastsScheduled);
16431             }
16432             pw.println("  mHandler:");
16433             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16434             needSep = true;
16435             printedAnything = true;
16436         }
16437
16438         if (!printedAnything) {
16439             pw.println("  (nothing)");
16440         }
16441     }
16442
16443     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16444             int opti, boolean dumpAll, String dumpPackage) {
16445         if (mCurBroadcastStats == null) {
16446             return;
16447         }
16448
16449         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16450         final long now = SystemClock.elapsedRealtime();
16451         if (mLastBroadcastStats != null) {
16452             pw.print("  Last stats (from ");
16453             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16454             pw.print(" to ");
16455             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16456             pw.print(", ");
16457             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16458                     - mLastBroadcastStats.mStartUptime, pw);
16459             pw.println(" uptime):");
16460             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16461                 pw.println("    (nothing)");
16462             }
16463             pw.println();
16464         }
16465         pw.print("  Current stats (from ");
16466         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16467         pw.print(" to now, ");
16468         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16469                 - mCurBroadcastStats.mStartUptime, pw);
16470         pw.println(" uptime):");
16471         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16472             pw.println("    (nothing)");
16473         }
16474     }
16475
16476     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16477             int opti, boolean fullCheckin, String dumpPackage) {
16478         if (mCurBroadcastStats == null) {
16479             return;
16480         }
16481
16482         if (mLastBroadcastStats != null) {
16483             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16484             if (fullCheckin) {
16485                 mLastBroadcastStats = null;
16486                 return;
16487             }
16488         }
16489         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16490         if (fullCheckin) {
16491             mCurBroadcastStats = null;
16492         }
16493     }
16494
16495     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16496             int opti, boolean dumpAll, String dumpPackage) {
16497         boolean needSep;
16498         boolean printedAnything = false;
16499
16500         ItemMatcher matcher = new ItemMatcher();
16501         matcher.build(args, opti);
16502
16503         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16504
16505         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16506         printedAnything |= needSep;
16507
16508         if (mLaunchingProviders.size() > 0) {
16509             boolean printed = false;
16510             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16511                 ContentProviderRecord r = mLaunchingProviders.get(i);
16512                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16513                     continue;
16514                 }
16515                 if (!printed) {
16516                     if (needSep) pw.println();
16517                     needSep = true;
16518                     pw.println("  Launching content providers:");
16519                     printed = true;
16520                     printedAnything = true;
16521                 }
16522                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16523                         pw.println(r);
16524             }
16525         }
16526
16527         if (!printedAnything) {
16528             pw.println("  (nothing)");
16529         }
16530     }
16531
16532     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16533             int opti, boolean dumpAll, String dumpPackage) {
16534         boolean needSep = false;
16535         boolean printedAnything = false;
16536
16537         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16538
16539         if (mGrantedUriPermissions.size() > 0) {
16540             boolean printed = false;
16541             int dumpUid = -2;
16542             if (dumpPackage != null) {
16543                 try {
16544                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16545                             MATCH_ANY_USER, 0);
16546                 } catch (NameNotFoundException e) {
16547                     dumpUid = -1;
16548                 }
16549             }
16550             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16551                 int uid = mGrantedUriPermissions.keyAt(i);
16552                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16553                     continue;
16554                 }
16555                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16556                 if (!printed) {
16557                     if (needSep) pw.println();
16558                     needSep = true;
16559                     pw.println("  Granted Uri Permissions:");
16560                     printed = true;
16561                     printedAnything = true;
16562                 }
16563                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16564                 for (UriPermission perm : perms.values()) {
16565                     pw.print("    "); pw.println(perm);
16566                     if (dumpAll) {
16567                         perm.dump(pw, "      ");
16568                     }
16569                 }
16570             }
16571         }
16572
16573         if (!printedAnything) {
16574             pw.println("  (nothing)");
16575         }
16576     }
16577
16578     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16579             int opti, boolean dumpAll, String dumpPackage) {
16580         boolean printed = false;
16581
16582         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16583
16584         if (mIntentSenderRecords.size() > 0) {
16585             // Organize these by package name, so they are easier to read.
16586             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16587             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16588             final Iterator<WeakReference<PendingIntentRecord>> it
16589                     = mIntentSenderRecords.values().iterator();
16590             while (it.hasNext()) {
16591                 WeakReference<PendingIntentRecord> ref = it.next();
16592                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16593                 if (rec == null) {
16594                     weakRefs.add(ref);
16595                     continue;
16596                 }
16597                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16598                     continue;
16599                 }
16600                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16601                 if (list == null) {
16602                     list = new ArrayList<>();
16603                     byPackage.put(rec.key.packageName, list);
16604                 }
16605                 list.add(rec);
16606             }
16607             for (int i = 0; i < byPackage.size(); i++) {
16608                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16609                 printed = true;
16610                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16611                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16612                 for (int j = 0; j < intents.size(); j++) {
16613                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16614                     if (dumpAll) {
16615                         intents.get(j).dump(pw, "      ");
16616                     }
16617                 }
16618             }
16619             if (weakRefs.size() > 0) {
16620                 printed = true;
16621                 pw.println("  * WEAK REFS:");
16622                 for (int i = 0; i < weakRefs.size(); i++) {
16623                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16624                 }
16625             }
16626         }
16627
16628         if (!printed) {
16629             pw.println("  (nothing)");
16630         }
16631     }
16632
16633     private static final int dumpProcessList(PrintWriter pw,
16634             ActivityManagerService service, List list,
16635             String prefix, String normalLabel, String persistentLabel,
16636             String dumpPackage) {
16637         int numPers = 0;
16638         final int N = list.size()-1;
16639         for (int i=N; i>=0; i--) {
16640             ProcessRecord r = (ProcessRecord)list.get(i);
16641             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16642                 continue;
16643             }
16644             pw.println(String.format("%s%s #%2d: %s",
16645                     prefix, (r.persistent ? persistentLabel : normalLabel),
16646                     i, r.toString()));
16647             if (r.persistent) {
16648                 numPers++;
16649             }
16650         }
16651         return numPers;
16652     }
16653
16654     private static final boolean dumpProcessOomList(PrintWriter pw,
16655             ActivityManagerService service, List<ProcessRecord> origList,
16656             String prefix, String normalLabel, String persistentLabel,
16657             boolean inclDetails, String dumpPackage) {
16658
16659         ArrayList<Pair<ProcessRecord, Integer>> list
16660                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16661         for (int i=0; i<origList.size(); i++) {
16662             ProcessRecord r = origList.get(i);
16663             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16664                 continue;
16665             }
16666             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16667         }
16668
16669         if (list.size() <= 0) {
16670             return false;
16671         }
16672
16673         Comparator<Pair<ProcessRecord, Integer>> comparator
16674                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16675             @Override
16676             public int compare(Pair<ProcessRecord, Integer> object1,
16677                     Pair<ProcessRecord, Integer> object2) {
16678                 if (object1.first.setAdj != object2.first.setAdj) {
16679                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16680                 }
16681                 if (object1.first.setProcState != object2.first.setProcState) {
16682                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16683                 }
16684                 if (object1.second.intValue() != object2.second.intValue()) {
16685                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16686                 }
16687                 return 0;
16688             }
16689         };
16690
16691         Collections.sort(list, comparator);
16692
16693         final long curUptime = SystemClock.uptimeMillis();
16694         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16695
16696         for (int i=list.size()-1; i>=0; i--) {
16697             ProcessRecord r = list.get(i).first;
16698             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16699             char schedGroup;
16700             switch (r.setSchedGroup) {
16701                 case ProcessList.SCHED_GROUP_BACKGROUND:
16702                     schedGroup = 'B';
16703                     break;
16704                 case ProcessList.SCHED_GROUP_DEFAULT:
16705                     schedGroup = 'F';
16706                     break;
16707                 case ProcessList.SCHED_GROUP_TOP_APP:
16708                     schedGroup = 'T';
16709                     break;
16710                 default:
16711                     schedGroup = '?';
16712                     break;
16713             }
16714             char foreground;
16715             if (r.foregroundActivities) {
16716                 foreground = 'A';
16717             } else if (r.foregroundServices) {
16718                 foreground = 'S';
16719             } else {
16720                 foreground = ' ';
16721             }
16722             String procState = ProcessList.makeProcStateString(r.curProcState);
16723             pw.print(prefix);
16724             pw.print(r.persistent ? persistentLabel : normalLabel);
16725             pw.print(" #");
16726             int num = (origList.size()-1)-list.get(i).second;
16727             if (num < 10) pw.print(' ');
16728             pw.print(num);
16729             pw.print(": ");
16730             pw.print(oomAdj);
16731             pw.print(' ');
16732             pw.print(schedGroup);
16733             pw.print('/');
16734             pw.print(foreground);
16735             pw.print('/');
16736             pw.print(procState);
16737             pw.print(" trm:");
16738             if (r.trimMemoryLevel < 10) pw.print(' ');
16739             pw.print(r.trimMemoryLevel);
16740             pw.print(' ');
16741             pw.print(r.toShortString());
16742             pw.print(" (");
16743             pw.print(r.adjType);
16744             pw.println(')');
16745             if (r.adjSource != null || r.adjTarget != null) {
16746                 pw.print(prefix);
16747                 pw.print("    ");
16748                 if (r.adjTarget instanceof ComponentName) {
16749                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16750                 } else if (r.adjTarget != null) {
16751                     pw.print(r.adjTarget.toString());
16752                 } else {
16753                     pw.print("{null}");
16754                 }
16755                 pw.print("<=");
16756                 if (r.adjSource instanceof ProcessRecord) {
16757                     pw.print("Proc{");
16758                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16759                     pw.println("}");
16760                 } else if (r.adjSource != null) {
16761                     pw.println(r.adjSource.toString());
16762                 } else {
16763                     pw.println("{null}");
16764                 }
16765             }
16766             if (inclDetails) {
16767                 pw.print(prefix);
16768                 pw.print("    ");
16769                 pw.print("oom: max="); pw.print(r.maxAdj);
16770                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16771                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16772                 pw.print(" cur="); pw.print(r.curAdj);
16773                 pw.print(" set="); pw.println(r.setAdj);
16774                 pw.print(prefix);
16775                 pw.print("    ");
16776                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16777                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16778                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16779                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16780                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16781                 pw.println();
16782                 pw.print(prefix);
16783                 pw.print("    ");
16784                 pw.print("cached="); pw.print(r.cached);
16785                 pw.print(" empty="); pw.print(r.empty);
16786                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16787
16788                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16789                     if (r.lastCpuTime != 0) {
16790                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16791                         pw.print(prefix);
16792                         pw.print("    ");
16793                         pw.print("run cpu over ");
16794                         TimeUtils.formatDuration(uptimeSince, pw);
16795                         pw.print(" used ");
16796                         TimeUtils.formatDuration(timeUsed, pw);
16797                         pw.print(" (");
16798                         pw.print((timeUsed*100)/uptimeSince);
16799                         pw.println("%)");
16800                     }
16801                 }
16802             }
16803         }
16804         return true;
16805     }
16806
16807     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16808             String[] args) {
16809         ArrayList<ProcessRecord> procs;
16810         synchronized (this) {
16811             if (args != null && args.length > start
16812                     && args[start].charAt(0) != '-') {
16813                 procs = new ArrayList<ProcessRecord>();
16814                 int pid = -1;
16815                 try {
16816                     pid = Integer.parseInt(args[start]);
16817                 } catch (NumberFormatException e) {
16818                 }
16819                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16820                     ProcessRecord proc = mLruProcesses.get(i);
16821                     if (proc.pid == pid) {
16822                         procs.add(proc);
16823                     } else if (allPkgs && proc.pkgList != null
16824                             && proc.pkgList.containsKey(args[start])) {
16825                         procs.add(proc);
16826                     } else if (proc.processName.equals(args[start])) {
16827                         procs.add(proc);
16828                     }
16829                 }
16830                 if (procs.size() <= 0) {
16831                     return null;
16832                 }
16833             } else {
16834                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16835             }
16836         }
16837         return procs;
16838     }
16839
16840     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16841             PrintWriter pw, String[] args) {
16842         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16843         if (procs == null) {
16844             pw.println("No process found for: " + args[0]);
16845             return;
16846         }
16847
16848         long uptime = SystemClock.uptimeMillis();
16849         long realtime = SystemClock.elapsedRealtime();
16850         pw.println("Applications Graphics Acceleration Info:");
16851         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16852
16853         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16854             ProcessRecord r = procs.get(i);
16855             if (r.thread != null) {
16856                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16857                 pw.flush();
16858                 try {
16859                     TransferPipe tp = new TransferPipe();
16860                     try {
16861                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16862                         tp.go(fd);
16863                     } finally {
16864                         tp.kill();
16865                     }
16866                 } catch (IOException e) {
16867                     pw.println("Failure while dumping the app: " + r);
16868                     pw.flush();
16869                 } catch (RemoteException e) {
16870                     pw.println("Got a RemoteException while dumping the app " + r);
16871                     pw.flush();
16872                 }
16873             }
16874         }
16875     }
16876
16877     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16878         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16879         if (procs == null) {
16880             pw.println("No process found for: " + args[0]);
16881             return;
16882         }
16883
16884         pw.println("Applications Database Info:");
16885
16886         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16887             ProcessRecord r = procs.get(i);
16888             if (r.thread != null) {
16889                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16890                 pw.flush();
16891                 try {
16892                     TransferPipe tp = new TransferPipe();
16893                     try {
16894                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16895                         tp.go(fd);
16896                     } finally {
16897                         tp.kill();
16898                     }
16899                 } catch (IOException e) {
16900                     pw.println("Failure while dumping the app: " + r);
16901                     pw.flush();
16902                 } catch (RemoteException e) {
16903                     pw.println("Got a RemoteException while dumping the app " + r);
16904                     pw.flush();
16905                 }
16906             }
16907         }
16908     }
16909
16910     final static class MemItem {
16911         final boolean isProc;
16912         final String label;
16913         final String shortLabel;
16914         final long pss;
16915         final long swapPss;
16916         final int id;
16917         final boolean hasActivities;
16918         ArrayList<MemItem> subitems;
16919
16920         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16921                 boolean _hasActivities) {
16922             isProc = true;
16923             label = _label;
16924             shortLabel = _shortLabel;
16925             pss = _pss;
16926             swapPss = _swapPss;
16927             id = _id;
16928             hasActivities = _hasActivities;
16929         }
16930
16931         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16932             isProc = false;
16933             label = _label;
16934             shortLabel = _shortLabel;
16935             pss = _pss;
16936             swapPss = _swapPss;
16937             id = _id;
16938             hasActivities = false;
16939         }
16940     }
16941
16942     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16943             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16944         if (sort && !isCompact) {
16945             Collections.sort(items, new Comparator<MemItem>() {
16946                 @Override
16947                 public int compare(MemItem lhs, MemItem rhs) {
16948                     if (lhs.pss < rhs.pss) {
16949                         return 1;
16950                     } else if (lhs.pss > rhs.pss) {
16951                         return -1;
16952                     }
16953                     return 0;
16954                 }
16955             });
16956         }
16957
16958         for (int i=0; i<items.size(); i++) {
16959             MemItem mi = items.get(i);
16960             if (!isCompact) {
16961                 if (dumpSwapPss) {
16962                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16963                             mi.label, stringifyKBSize(mi.swapPss));
16964                 } else {
16965                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16966                 }
16967             } else if (mi.isProc) {
16968                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16969                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16970                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16971                 pw.println(mi.hasActivities ? ",a" : ",e");
16972             } else {
16973                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16974                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16975             }
16976             if (mi.subitems != null) {
16977                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16978                         true, isCompact, dumpSwapPss);
16979             }
16980         }
16981     }
16982
16983     // These are in KB.
16984     static final long[] DUMP_MEM_BUCKETS = new long[] {
16985         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16986         120*1024, 160*1024, 200*1024,
16987         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16988         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16989     };
16990
16991     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16992             boolean stackLike) {
16993         int start = label.lastIndexOf('.');
16994         if (start >= 0) start++;
16995         else start = 0;
16996         int end = label.length();
16997         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16998             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16999                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17000                 out.append(bucket);
17001                 out.append(stackLike ? "MB." : "MB ");
17002                 out.append(label, start, end);
17003                 return;
17004             }
17005         }
17006         out.append(memKB/1024);
17007         out.append(stackLike ? "MB." : "MB ");
17008         out.append(label, start, end);
17009     }
17010
17011     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17012             ProcessList.NATIVE_ADJ,
17013             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17014             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17015             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17016             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17017             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17018             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17019     };
17020     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17021             "Native",
17022             "System", "Persistent", "Persistent Service", "Foreground",
17023             "Visible", "Perceptible",
17024             "Heavy Weight", "Backup",
17025             "A Services", "Home",
17026             "Previous", "B Services", "Cached"
17027     };
17028     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17029             "native",
17030             "sys", "pers", "persvc", "fore",
17031             "vis", "percept",
17032             "heavy", "backup",
17033             "servicea", "home",
17034             "prev", "serviceb", "cached"
17035     };
17036
17037     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17038             long realtime, boolean isCheckinRequest, boolean isCompact) {
17039         if (isCompact) {
17040             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17041         }
17042         if (isCheckinRequest || isCompact) {
17043             // short checkin version
17044             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17045         } else {
17046             pw.println("Applications Memory Usage (in Kilobytes):");
17047             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17048         }
17049     }
17050
17051     private static final int KSM_SHARED = 0;
17052     private static final int KSM_SHARING = 1;
17053     private static final int KSM_UNSHARED = 2;
17054     private static final int KSM_VOLATILE = 3;
17055
17056     private final long[] getKsmInfo() {
17057         long[] longOut = new long[4];
17058         final int[] SINGLE_LONG_FORMAT = new int[] {
17059             PROC_SPACE_TERM| PROC_OUT_LONG
17060         };
17061         long[] longTmp = new long[1];
17062         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17063                 SINGLE_LONG_FORMAT, null, longTmp, null);
17064         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17065         longTmp[0] = 0;
17066         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17067                 SINGLE_LONG_FORMAT, null, longTmp, null);
17068         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17069         longTmp[0] = 0;
17070         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17071                 SINGLE_LONG_FORMAT, null, longTmp, null);
17072         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17073         longTmp[0] = 0;
17074         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17075                 SINGLE_LONG_FORMAT, null, longTmp, null);
17076         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17077         return longOut;
17078     }
17079
17080     private static String stringifySize(long size, int order) {
17081         Locale locale = Locale.US;
17082         switch (order) {
17083             case 1:
17084                 return String.format(locale, "%,13d", size);
17085             case 1024:
17086                 return String.format(locale, "%,9dK", size / 1024);
17087             case 1024 * 1024:
17088                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17089             case 1024 * 1024 * 1024:
17090                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17091             default:
17092                 throw new IllegalArgumentException("Invalid size order");
17093         }
17094     }
17095
17096     private static String stringifyKBSize(long size) {
17097         return stringifySize(size * 1024, 1024);
17098     }
17099
17100     // Update this version number in case you change the 'compact' format
17101     private static final int MEMINFO_COMPACT_VERSION = 1;
17102
17103     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17104             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17105         boolean dumpDetails = false;
17106         boolean dumpFullDetails = false;
17107         boolean dumpDalvik = false;
17108         boolean dumpSummaryOnly = false;
17109         boolean dumpUnreachable = false;
17110         boolean oomOnly = false;
17111         boolean isCompact = false;
17112         boolean localOnly = false;
17113         boolean packages = false;
17114         boolean isCheckinRequest = false;
17115         boolean dumpSwapPss = false;
17116
17117         int opti = 0;
17118         while (opti < args.length) {
17119             String opt = args[opti];
17120             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17121                 break;
17122             }
17123             opti++;
17124             if ("-a".equals(opt)) {
17125                 dumpDetails = true;
17126                 dumpFullDetails = true;
17127                 dumpDalvik = true;
17128                 dumpSwapPss = true;
17129             } else if ("-d".equals(opt)) {
17130                 dumpDalvik = true;
17131             } else if ("-c".equals(opt)) {
17132                 isCompact = true;
17133             } else if ("-s".equals(opt)) {
17134                 dumpDetails = true;
17135                 dumpSummaryOnly = true;
17136             } else if ("-S".equals(opt)) {
17137                 dumpSwapPss = true;
17138             } else if ("--unreachable".equals(opt)) {
17139                 dumpUnreachable = true;
17140             } else if ("--oom".equals(opt)) {
17141                 oomOnly = true;
17142             } else if ("--local".equals(opt)) {
17143                 localOnly = true;
17144             } else if ("--package".equals(opt)) {
17145                 packages = true;
17146             } else if ("--checkin".equals(opt)) {
17147                 isCheckinRequest = true;
17148
17149             } else if ("-h".equals(opt)) {
17150                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17151                 pw.println("  -a: include all available information for each process.");
17152                 pw.println("  -d: include dalvik details.");
17153                 pw.println("  -c: dump in a compact machine-parseable representation.");
17154                 pw.println("  -s: dump only summary of application memory usage.");
17155                 pw.println("  -S: dump also SwapPss.");
17156                 pw.println("  --oom: only show processes organized by oom adj.");
17157                 pw.println("  --local: only collect details locally, don't call process.");
17158                 pw.println("  --package: interpret process arg as package, dumping all");
17159                 pw.println("             processes that have loaded that package.");
17160                 pw.println("  --checkin: dump data for a checkin");
17161                 pw.println("If [process] is specified it can be the name or ");
17162                 pw.println("pid of a specific process to dump.");
17163                 return;
17164             } else {
17165                 pw.println("Unknown argument: " + opt + "; use -h for help");
17166             }
17167         }
17168
17169         long uptime = SystemClock.uptimeMillis();
17170         long realtime = SystemClock.elapsedRealtime();
17171         final long[] tmpLong = new long[1];
17172
17173         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17174         if (procs == null) {
17175             // No Java processes.  Maybe they want to print a native process.
17176             if (args != null && args.length > opti
17177                     && args[opti].charAt(0) != '-') {
17178                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17179                         = new ArrayList<ProcessCpuTracker.Stats>();
17180                 updateCpuStatsNow();
17181                 int findPid = -1;
17182                 try {
17183                     findPid = Integer.parseInt(args[opti]);
17184                 } catch (NumberFormatException e) {
17185                 }
17186                 synchronized (mProcessCpuTracker) {
17187                     final int N = mProcessCpuTracker.countStats();
17188                     for (int i=0; i<N; i++) {
17189                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17190                         if (st.pid == findPid || (st.baseName != null
17191                                 && st.baseName.equals(args[opti]))) {
17192                             nativeProcs.add(st);
17193                         }
17194                     }
17195                 }
17196                 if (nativeProcs.size() > 0) {
17197                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17198                             isCompact);
17199                     Debug.MemoryInfo mi = null;
17200                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17201                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17202                         final int pid = r.pid;
17203                         if (!isCheckinRequest && dumpDetails) {
17204                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17205                         }
17206                         if (mi == null) {
17207                             mi = new Debug.MemoryInfo();
17208                         }
17209                         if (dumpDetails || (!brief && !oomOnly)) {
17210                             Debug.getMemoryInfo(pid, mi);
17211                         } else {
17212                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17213                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17214                         }
17215                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17216                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17217                         if (isCheckinRequest) {
17218                             pw.println();
17219                         }
17220                     }
17221                     return;
17222                 }
17223             }
17224             pw.println("No process found for: " + args[opti]);
17225             return;
17226         }
17227
17228         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17229             dumpDetails = true;
17230         }
17231
17232         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17233
17234         String[] innerArgs = new String[args.length-opti];
17235         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17236
17237         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17238         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17239         long nativePss = 0;
17240         long nativeSwapPss = 0;
17241         long dalvikPss = 0;
17242         long dalvikSwapPss = 0;
17243         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17244                 EmptyArray.LONG;
17245         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17246                 EmptyArray.LONG;
17247         long otherPss = 0;
17248         long otherSwapPss = 0;
17249         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17250         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17251
17252         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17253         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17254         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17255                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17256
17257         long totalPss = 0;
17258         long totalSwapPss = 0;
17259         long cachedPss = 0;
17260         long cachedSwapPss = 0;
17261         boolean hasSwapPss = false;
17262
17263         Debug.MemoryInfo mi = null;
17264         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17265             final ProcessRecord r = procs.get(i);
17266             final IApplicationThread thread;
17267             final int pid;
17268             final int oomAdj;
17269             final boolean hasActivities;
17270             synchronized (this) {
17271                 thread = r.thread;
17272                 pid = r.pid;
17273                 oomAdj = r.getSetAdjWithServices();
17274                 hasActivities = r.activities.size() > 0;
17275             }
17276             if (thread != null) {
17277                 if (!isCheckinRequest && dumpDetails) {
17278                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17279                 }
17280                 if (mi == null) {
17281                     mi = new Debug.MemoryInfo();
17282                 }
17283                 if (dumpDetails || (!brief && !oomOnly)) {
17284                     Debug.getMemoryInfo(pid, mi);
17285                     hasSwapPss = mi.hasSwappedOutPss;
17286                 } else {
17287                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17288                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17289                 }
17290                 if (dumpDetails) {
17291                     if (localOnly) {
17292                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17293                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17294                         if (isCheckinRequest) {
17295                             pw.println();
17296                         }
17297                     } else {
17298                         pw.flush();
17299                         try {
17300                             TransferPipe tp = new TransferPipe();
17301                             try {
17302                                 thread.dumpMemInfo(tp.getWriteFd(),
17303                                         mi, isCheckinRequest, dumpFullDetails,
17304                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17305                                 tp.go(fd);
17306                             } finally {
17307                                 tp.kill();
17308                             }
17309                         } catch (IOException e) {
17310                             if (!isCheckinRequest) {
17311                                 pw.println("Got IoException! " + e);
17312                                 pw.flush();
17313                             }
17314                         } catch (RemoteException e) {
17315                             if (!isCheckinRequest) {
17316                                 pw.println("Got RemoteException! " + e);
17317                                 pw.flush();
17318                             }
17319                         }
17320                     }
17321                 }
17322
17323                 final long myTotalPss = mi.getTotalPss();
17324                 final long myTotalUss = mi.getTotalUss();
17325                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17326
17327                 synchronized (this) {
17328                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17329                         // Record this for posterity if the process has been stable.
17330                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17331                     }
17332                 }
17333
17334                 if (!isCheckinRequest && mi != null) {
17335                     totalPss += myTotalPss;
17336                     totalSwapPss += myTotalSwapPss;
17337                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17338                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17339                             myTotalSwapPss, pid, hasActivities);
17340                     procMems.add(pssItem);
17341                     procMemsMap.put(pid, pssItem);
17342
17343                     nativePss += mi.nativePss;
17344                     nativeSwapPss += mi.nativeSwappedOutPss;
17345                     dalvikPss += mi.dalvikPss;
17346                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17347                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17348                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17349                         dalvikSubitemSwapPss[j] +=
17350                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17351                     }
17352                     otherPss += mi.otherPss;
17353                     otherSwapPss += mi.otherSwappedOutPss;
17354                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17355                         long mem = mi.getOtherPss(j);
17356                         miscPss[j] += mem;
17357                         otherPss -= mem;
17358                         mem = mi.getOtherSwappedOutPss(j);
17359                         miscSwapPss[j] += mem;
17360                         otherSwapPss -= mem;
17361                     }
17362
17363                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17364                         cachedPss += myTotalPss;
17365                         cachedSwapPss += myTotalSwapPss;
17366                     }
17367
17368                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17369                         if (oomIndex == (oomPss.length - 1)
17370                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17371                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17372                             oomPss[oomIndex] += myTotalPss;
17373                             oomSwapPss[oomIndex] += myTotalSwapPss;
17374                             if (oomProcs[oomIndex] == null) {
17375                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17376                             }
17377                             oomProcs[oomIndex].add(pssItem);
17378                             break;
17379                         }
17380                     }
17381                 }
17382             }
17383         }
17384
17385         long nativeProcTotalPss = 0;
17386
17387         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17388             // If we are showing aggregations, also look for native processes to
17389             // include so that our aggregations are more accurate.
17390             updateCpuStatsNow();
17391             mi = null;
17392             synchronized (mProcessCpuTracker) {
17393                 final int N = mProcessCpuTracker.countStats();
17394                 for (int i=0; i<N; i++) {
17395                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17396                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17397                         if (mi == null) {
17398                             mi = new Debug.MemoryInfo();
17399                         }
17400                         if (!brief && !oomOnly) {
17401                             Debug.getMemoryInfo(st.pid, mi);
17402                         } else {
17403                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17404                             mi.nativePrivateDirty = (int)tmpLong[0];
17405                         }
17406
17407                         final long myTotalPss = mi.getTotalPss();
17408                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17409                         totalPss += myTotalPss;
17410                         nativeProcTotalPss += myTotalPss;
17411
17412                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17413                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17414                         procMems.add(pssItem);
17415
17416                         nativePss += mi.nativePss;
17417                         nativeSwapPss += mi.nativeSwappedOutPss;
17418                         dalvikPss += mi.dalvikPss;
17419                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17420                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17421                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17422                             dalvikSubitemSwapPss[j] +=
17423                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17424                         }
17425                         otherPss += mi.otherPss;
17426                         otherSwapPss += mi.otherSwappedOutPss;
17427                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17428                             long mem = mi.getOtherPss(j);
17429                             miscPss[j] += mem;
17430                             otherPss -= mem;
17431                             mem = mi.getOtherSwappedOutPss(j);
17432                             miscSwapPss[j] += mem;
17433                             otherSwapPss -= mem;
17434                         }
17435                         oomPss[0] += myTotalPss;
17436                         oomSwapPss[0] += myTotalSwapPss;
17437                         if (oomProcs[0] == null) {
17438                             oomProcs[0] = new ArrayList<MemItem>();
17439                         }
17440                         oomProcs[0].add(pssItem);
17441                     }
17442                 }
17443             }
17444
17445             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17446
17447             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17448             final int dalvikId = -2;
17449             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17450             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17451             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17452                 String label = Debug.MemoryInfo.getOtherLabel(j);
17453                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17454             }
17455             if (dalvikSubitemPss.length > 0) {
17456                 // Add dalvik subitems.
17457                 for (MemItem memItem : catMems) {
17458                     int memItemStart = 0, memItemEnd = 0;
17459                     if (memItem.id == dalvikId) {
17460                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17461                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17462                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17463                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17464                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17465                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17466                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17467                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17468                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17469                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17470                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17471                     } else {
17472                         continue;  // No subitems, continue.
17473                     }
17474                     memItem.subitems = new ArrayList<MemItem>();
17475                     for (int j=memItemStart; j<=memItemEnd; j++) {
17476                         final String name = Debug.MemoryInfo.getOtherLabel(
17477                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17478                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17479                                 dalvikSubitemSwapPss[j], j));
17480                     }
17481                 }
17482             }
17483
17484             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17485             for (int j=0; j<oomPss.length; j++) {
17486                 if (oomPss[j] != 0) {
17487                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17488                             : DUMP_MEM_OOM_LABEL[j];
17489                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17490                             DUMP_MEM_OOM_ADJ[j]);
17491                     item.subitems = oomProcs[j];
17492                     oomMems.add(item);
17493                 }
17494             }
17495
17496             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17497             if (!brief && !oomOnly && !isCompact) {
17498                 pw.println();
17499                 pw.println("Total PSS by process:");
17500                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17501                 pw.println();
17502             }
17503             if (!isCompact) {
17504                 pw.println("Total PSS by OOM adjustment:");
17505             }
17506             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17507             if (!brief && !oomOnly) {
17508                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17509                 if (!isCompact) {
17510                     out.println();
17511                     out.println("Total PSS by category:");
17512                 }
17513                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17514             }
17515             if (!isCompact) {
17516                 pw.println();
17517             }
17518             MemInfoReader memInfo = new MemInfoReader();
17519             memInfo.readMemInfo();
17520             if (nativeProcTotalPss > 0) {
17521                 synchronized (this) {
17522                     final long cachedKb = memInfo.getCachedSizeKb();
17523                     final long freeKb = memInfo.getFreeSizeKb();
17524                     final long zramKb = memInfo.getZramTotalSizeKb();
17525                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17526                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17527                             kernelKb*1024, nativeProcTotalPss*1024);
17528                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17529                             nativeProcTotalPss);
17530                 }
17531             }
17532             if (!brief) {
17533                 if (!isCompact) {
17534                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17535                     pw.print(" (status ");
17536                     switch (mLastMemoryLevel) {
17537                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17538                             pw.println("normal)");
17539                             break;
17540                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17541                             pw.println("moderate)");
17542                             break;
17543                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17544                             pw.println("low)");
17545                             break;
17546                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17547                             pw.println("critical)");
17548                             break;
17549                         default:
17550                             pw.print(mLastMemoryLevel);
17551                             pw.println(")");
17552                             break;
17553                     }
17554                     pw.print(" Free RAM: ");
17555                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17556                             + memInfo.getFreeSizeKb()));
17557                     pw.print(" (");
17558                     pw.print(stringifyKBSize(cachedPss));
17559                     pw.print(" cached pss + ");
17560                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17561                     pw.print(" cached kernel + ");
17562                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17563                     pw.println(" free)");
17564                 } else {
17565                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17566                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17567                             + memInfo.getFreeSizeKb()); pw.print(",");
17568                     pw.println(totalPss - cachedPss);
17569                 }
17570             }
17571             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17572                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17573                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17574             if (!isCompact) {
17575                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17576                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17577                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17578                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17579                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17580             } else {
17581                 pw.print("lostram,"); pw.println(lostRAM);
17582             }
17583             if (!brief) {
17584                 if (memInfo.getZramTotalSizeKb() != 0) {
17585                     if (!isCompact) {
17586                         pw.print("     ZRAM: ");
17587                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17588                                 pw.print(" physical used for ");
17589                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17590                                         - memInfo.getSwapFreeSizeKb()));
17591                                 pw.print(" in swap (");
17592                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17593                                 pw.println(" total swap)");
17594                     } else {
17595                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17596                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17597                                 pw.println(memInfo.getSwapFreeSizeKb());
17598                     }
17599                 }
17600                 final long[] ksm = getKsmInfo();
17601                 if (!isCompact) {
17602                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17603                             || ksm[KSM_VOLATILE] != 0) {
17604                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17605                                 pw.print(" saved from shared ");
17606                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17607                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17608                                 pw.print(" unshared; ");
17609                                 pw.print(stringifyKBSize(
17610                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17611                     }
17612                     pw.print("   Tuning: ");
17613                     pw.print(ActivityManager.staticGetMemoryClass());
17614                     pw.print(" (large ");
17615                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17616                     pw.print("), oom ");
17617                     pw.print(stringifySize(
17618                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17619                     pw.print(", restore limit ");
17620                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17621                     if (ActivityManager.isLowRamDeviceStatic()) {
17622                         pw.print(" (low-ram)");
17623                     }
17624                     if (ActivityManager.isHighEndGfx()) {
17625                         pw.print(" (high-end-gfx)");
17626                     }
17627                     pw.println();
17628                 } else {
17629                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17630                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17631                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17632                     pw.print("tuning,");
17633                     pw.print(ActivityManager.staticGetMemoryClass());
17634                     pw.print(',');
17635                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17636                     pw.print(',');
17637                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17638                     if (ActivityManager.isLowRamDeviceStatic()) {
17639                         pw.print(",low-ram");
17640                     }
17641                     if (ActivityManager.isHighEndGfx()) {
17642                         pw.print(",high-end-gfx");
17643                     }
17644                     pw.println();
17645                 }
17646             }
17647         }
17648     }
17649
17650     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17651             long memtrack, String name) {
17652         sb.append("  ");
17653         sb.append(ProcessList.makeOomAdjString(oomAdj));
17654         sb.append(' ');
17655         sb.append(ProcessList.makeProcStateString(procState));
17656         sb.append(' ');
17657         ProcessList.appendRamKb(sb, pss);
17658         sb.append(": ");
17659         sb.append(name);
17660         if (memtrack > 0) {
17661             sb.append(" (");
17662             sb.append(stringifyKBSize(memtrack));
17663             sb.append(" memtrack)");
17664         }
17665     }
17666
17667     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17668         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17669         sb.append(" (pid ");
17670         sb.append(mi.pid);
17671         sb.append(") ");
17672         sb.append(mi.adjType);
17673         sb.append('\n');
17674         if (mi.adjReason != null) {
17675             sb.append("                      ");
17676             sb.append(mi.adjReason);
17677             sb.append('\n');
17678         }
17679     }
17680
17681     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17682         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17683         for (int i=0, N=memInfos.size(); i<N; i++) {
17684             ProcessMemInfo mi = memInfos.get(i);
17685             infoMap.put(mi.pid, mi);
17686         }
17687         updateCpuStatsNow();
17688         long[] memtrackTmp = new long[1];
17689         final List<ProcessCpuTracker.Stats> stats;
17690         // Get a list of Stats that have vsize > 0
17691         synchronized (mProcessCpuTracker) {
17692             stats = mProcessCpuTracker.getStats((st) -> {
17693                 return st.vsize > 0;
17694             });
17695         }
17696         final int statsCount = stats.size();
17697         for (int i = 0; i < statsCount; i++) {
17698             ProcessCpuTracker.Stats st = stats.get(i);
17699             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17700             if (pss > 0) {
17701                 if (infoMap.indexOfKey(st.pid) < 0) {
17702                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17703                             ProcessList.NATIVE_ADJ, -1, "native", null);
17704                     mi.pss = pss;
17705                     mi.memtrack = memtrackTmp[0];
17706                     memInfos.add(mi);
17707                 }
17708             }
17709         }
17710
17711         long totalPss = 0;
17712         long totalMemtrack = 0;
17713         for (int i=0, N=memInfos.size(); i<N; i++) {
17714             ProcessMemInfo mi = memInfos.get(i);
17715             if (mi.pss == 0) {
17716                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17717                 mi.memtrack = memtrackTmp[0];
17718             }
17719             totalPss += mi.pss;
17720             totalMemtrack += mi.memtrack;
17721         }
17722         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17723             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17724                 if (lhs.oomAdj != rhs.oomAdj) {
17725                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17726                 }
17727                 if (lhs.pss != rhs.pss) {
17728                     return lhs.pss < rhs.pss ? 1 : -1;
17729                 }
17730                 return 0;
17731             }
17732         });
17733
17734         StringBuilder tag = new StringBuilder(128);
17735         StringBuilder stack = new StringBuilder(128);
17736         tag.append("Low on memory -- ");
17737         appendMemBucket(tag, totalPss, "total", false);
17738         appendMemBucket(stack, totalPss, "total", true);
17739
17740         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17741         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17742         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17743
17744         boolean firstLine = true;
17745         int lastOomAdj = Integer.MIN_VALUE;
17746         long extraNativeRam = 0;
17747         long extraNativeMemtrack = 0;
17748         long cachedPss = 0;
17749         for (int i=0, N=memInfos.size(); i<N; i++) {
17750             ProcessMemInfo mi = memInfos.get(i);
17751
17752             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17753                 cachedPss += mi.pss;
17754             }
17755
17756             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17757                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17758                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17759                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17760                 if (lastOomAdj != mi.oomAdj) {
17761                     lastOomAdj = mi.oomAdj;
17762                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17763                         tag.append(" / ");
17764                     }
17765                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17766                         if (firstLine) {
17767                             stack.append(":");
17768                             firstLine = false;
17769                         }
17770                         stack.append("\n\t at ");
17771                     } else {
17772                         stack.append("$");
17773                     }
17774                 } else {
17775                     tag.append(" ");
17776                     stack.append("$");
17777                 }
17778                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17779                     appendMemBucket(tag, mi.pss, mi.name, false);
17780                 }
17781                 appendMemBucket(stack, mi.pss, mi.name, true);
17782                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17783                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17784                     stack.append("(");
17785                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17786                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17787                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17788                             stack.append(":");
17789                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17790                         }
17791                     }
17792                     stack.append(")");
17793                 }
17794             }
17795
17796             appendMemInfo(fullNativeBuilder, mi);
17797             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17798                 // The short form only has native processes that are >= 512K.
17799                 if (mi.pss >= 512) {
17800                     appendMemInfo(shortNativeBuilder, mi);
17801                 } else {
17802                     extraNativeRam += mi.pss;
17803                     extraNativeMemtrack += mi.memtrack;
17804                 }
17805             } else {
17806                 // Short form has all other details, but if we have collected RAM
17807                 // from smaller native processes let's dump a summary of that.
17808                 if (extraNativeRam > 0) {
17809                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17810                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17811                     shortNativeBuilder.append('\n');
17812                     extraNativeRam = 0;
17813                 }
17814                 appendMemInfo(fullJavaBuilder, mi);
17815             }
17816         }
17817
17818         fullJavaBuilder.append("           ");
17819         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17820         fullJavaBuilder.append(": TOTAL");
17821         if (totalMemtrack > 0) {
17822             fullJavaBuilder.append(" (");
17823             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17824             fullJavaBuilder.append(" memtrack)");
17825         } else {
17826         }
17827         fullJavaBuilder.append("\n");
17828
17829         MemInfoReader memInfo = new MemInfoReader();
17830         memInfo.readMemInfo();
17831         final long[] infos = memInfo.getRawInfo();
17832
17833         StringBuilder memInfoBuilder = new StringBuilder(1024);
17834         Debug.getMemInfo(infos);
17835         memInfoBuilder.append("  MemInfo: ");
17836         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17837         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17838         memInfoBuilder.append(stringifyKBSize(
17839                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17840         memInfoBuilder.append(stringifyKBSize(
17841                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17842         memInfoBuilder.append(stringifyKBSize(
17843                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17844         memInfoBuilder.append("           ");
17845         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17846         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17847         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17848         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17849         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17850             memInfoBuilder.append("  ZRAM: ");
17851             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17852             memInfoBuilder.append(" RAM, ");
17853             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17854             memInfoBuilder.append(" swap total, ");
17855             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17856             memInfoBuilder.append(" swap free\n");
17857         }
17858         final long[] ksm = getKsmInfo();
17859         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17860                 || ksm[KSM_VOLATILE] != 0) {
17861             memInfoBuilder.append("  KSM: ");
17862             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17863             memInfoBuilder.append(" saved from shared ");
17864             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17865             memInfoBuilder.append("\n       ");
17866             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17867             memInfoBuilder.append(" unshared; ");
17868             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17869             memInfoBuilder.append(" volatile\n");
17870         }
17871         memInfoBuilder.append("  Free RAM: ");
17872         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17873                 + memInfo.getFreeSizeKb()));
17874         memInfoBuilder.append("\n");
17875         memInfoBuilder.append("  Used RAM: ");
17876         memInfoBuilder.append(stringifyKBSize(
17877                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17878         memInfoBuilder.append("\n");
17879         memInfoBuilder.append("  Lost RAM: ");
17880         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17881                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17882                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17883         memInfoBuilder.append("\n");
17884         Slog.i(TAG, "Low on memory:");
17885         Slog.i(TAG, shortNativeBuilder.toString());
17886         Slog.i(TAG, fullJavaBuilder.toString());
17887         Slog.i(TAG, memInfoBuilder.toString());
17888
17889         StringBuilder dropBuilder = new StringBuilder(1024);
17890         /*
17891         StringWriter oomSw = new StringWriter();
17892         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17893         StringWriter catSw = new StringWriter();
17894         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17895         String[] emptyArgs = new String[] { };
17896         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17897         oomPw.flush();
17898         String oomString = oomSw.toString();
17899         */
17900         dropBuilder.append("Low on memory:");
17901         dropBuilder.append(stack);
17902         dropBuilder.append('\n');
17903         dropBuilder.append(fullNativeBuilder);
17904         dropBuilder.append(fullJavaBuilder);
17905         dropBuilder.append('\n');
17906         dropBuilder.append(memInfoBuilder);
17907         dropBuilder.append('\n');
17908         /*
17909         dropBuilder.append(oomString);
17910         dropBuilder.append('\n');
17911         */
17912         StringWriter catSw = new StringWriter();
17913         synchronized (ActivityManagerService.this) {
17914             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17915             String[] emptyArgs = new String[] { };
17916             catPw.println();
17917             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17918             catPw.println();
17919             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17920                     false, null).dumpLocked();
17921             catPw.println();
17922             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17923             catPw.flush();
17924         }
17925         dropBuilder.append(catSw.toString());
17926         addErrorToDropBox("lowmem", null, "system_server", null,
17927                 null, tag.toString(), dropBuilder.toString(), null, null);
17928         //Slog.i(TAG, "Sent to dropbox:");
17929         //Slog.i(TAG, dropBuilder.toString());
17930         synchronized (ActivityManagerService.this) {
17931             long now = SystemClock.uptimeMillis();
17932             if (mLastMemUsageReportTime < now) {
17933                 mLastMemUsageReportTime = now;
17934             }
17935         }
17936     }
17937
17938     /**
17939      * Searches array of arguments for the specified string
17940      * @param args array of argument strings
17941      * @param value value to search for
17942      * @return true if the value is contained in the array
17943      */
17944     private static boolean scanArgs(String[] args, String value) {
17945         if (args != null) {
17946             for (String arg : args) {
17947                 if (value.equals(arg)) {
17948                     return true;
17949                 }
17950             }
17951         }
17952         return false;
17953     }
17954
17955     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17956             ContentProviderRecord cpr, boolean always) {
17957         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17958
17959         if (!inLaunching || always) {
17960             synchronized (cpr) {
17961                 cpr.launchingApp = null;
17962                 cpr.notifyAll();
17963             }
17964             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17965             String names[] = cpr.info.authority.split(";");
17966             for (int j = 0; j < names.length; j++) {
17967                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17968             }
17969         }
17970
17971         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17972             ContentProviderConnection conn = cpr.connections.get(i);
17973             if (conn.waiting) {
17974                 // If this connection is waiting for the provider, then we don't
17975                 // need to mess with its process unless we are always removing
17976                 // or for some reason the provider is not currently launching.
17977                 if (inLaunching && !always) {
17978                     continue;
17979                 }
17980             }
17981             ProcessRecord capp = conn.client;
17982             conn.dead = true;
17983             if (conn.stableCount > 0) {
17984                 if (!capp.persistent && capp.thread != null
17985                         && capp.pid != 0
17986                         && capp.pid != MY_PID) {
17987                     capp.kill("depends on provider "
17988                             + cpr.name.flattenToShortString()
17989                             + " in dying proc " + (proc != null ? proc.processName : "??")
17990                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17991                 }
17992             } else if (capp.thread != null && conn.provider.provider != null) {
17993                 try {
17994                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17995                 } catch (RemoteException e) {
17996                 }
17997                 // In the protocol here, we don't expect the client to correctly
17998                 // clean up this connection, we'll just remove it.
17999                 cpr.connections.remove(i);
18000                 if (conn.client.conProviders.remove(conn)) {
18001                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18002                 }
18003             }
18004         }
18005
18006         if (inLaunching && always) {
18007             mLaunchingProviders.remove(cpr);
18008         }
18009         return inLaunching;
18010     }
18011
18012     /**
18013      * Main code for cleaning up a process when it has gone away.  This is
18014      * called both as a result of the process dying, or directly when stopping
18015      * a process when running in single process mode.
18016      *
18017      * @return Returns true if the given process has been restarted, so the
18018      * app that was passed in must remain on the process lists.
18019      */
18020     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18021             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18022         if (index >= 0) {
18023             removeLruProcessLocked(app);
18024             ProcessList.remove(app.pid);
18025         }
18026
18027         mProcessesToGc.remove(app);
18028         mPendingPssProcesses.remove(app);
18029
18030         // Dismiss any open dialogs.
18031         if (app.crashDialog != null && !app.forceCrashReport) {
18032             app.crashDialog.dismiss();
18033             app.crashDialog = null;
18034         }
18035         if (app.anrDialog != null) {
18036             app.anrDialog.dismiss();
18037             app.anrDialog = null;
18038         }
18039         if (app.waitDialog != null) {
18040             app.waitDialog.dismiss();
18041             app.waitDialog = null;
18042         }
18043
18044         app.crashing = false;
18045         app.notResponding = false;
18046
18047         app.resetPackageList(mProcessStats);
18048         app.unlinkDeathRecipient();
18049         app.makeInactive(mProcessStats);
18050         app.waitingToKill = null;
18051         app.forcingToImportant = null;
18052         updateProcessForegroundLocked(app, false, false);
18053         app.foregroundActivities = false;
18054         app.hasShownUi = false;
18055         app.treatLikeActivity = false;
18056         app.hasAboveClient = false;
18057         app.hasClientActivities = false;
18058
18059         mServices.killServicesLocked(app, allowRestart);
18060
18061         boolean restart = false;
18062
18063         // Remove published content providers.
18064         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18065             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18066             final boolean always = app.bad || !allowRestart;
18067             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18068             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18069                 // We left the provider in the launching list, need to
18070                 // restart it.
18071                 restart = true;
18072             }
18073
18074             cpr.provider = null;
18075             cpr.proc = null;
18076         }
18077         app.pubProviders.clear();
18078
18079         // Take care of any launching providers waiting for this process.
18080         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18081             restart = true;
18082         }
18083
18084         // Unregister from connected content providers.
18085         if (!app.conProviders.isEmpty()) {
18086             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18087                 ContentProviderConnection conn = app.conProviders.get(i);
18088                 conn.provider.connections.remove(conn);
18089                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18090                         conn.provider.name);
18091             }
18092             app.conProviders.clear();
18093         }
18094
18095         // At this point there may be remaining entries in mLaunchingProviders
18096         // where we were the only one waiting, so they are no longer of use.
18097         // Look for these and clean up if found.
18098         // XXX Commented out for now.  Trying to figure out a way to reproduce
18099         // the actual situation to identify what is actually going on.
18100         if (false) {
18101             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18102                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18103                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18104                     synchronized (cpr) {
18105                         cpr.launchingApp = null;
18106                         cpr.notifyAll();
18107                     }
18108                 }
18109             }
18110         }
18111
18112         skipCurrentReceiverLocked(app);
18113
18114         // Unregister any receivers.
18115         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18116             removeReceiverLocked(app.receivers.valueAt(i));
18117         }
18118         app.receivers.clear();
18119
18120         // If the app is undergoing backup, tell the backup manager about it
18121         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18122             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18123                     + mBackupTarget.appInfo + " died during backup");
18124             mHandler.post(new Runnable() {
18125                 @Override
18126                 public void run(){
18127                     try {
18128                         IBackupManager bm = IBackupManager.Stub.asInterface(
18129                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18130                         bm.agentDisconnected(app.info.packageName);
18131                     } catch (RemoteException e) {
18132                         // can't happen; backup manager is local
18133                     }
18134                 }
18135             });
18136         }
18137
18138         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18139             ProcessChangeItem item = mPendingProcessChanges.get(i);
18140             if (item.pid == app.pid) {
18141                 mPendingProcessChanges.remove(i);
18142                 mAvailProcessChanges.add(item);
18143             }
18144         }
18145         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18146                 null).sendToTarget();
18147
18148         // If the caller is restarting this app, then leave it in its
18149         // current lists and let the caller take care of it.
18150         if (restarting) {
18151             return false;
18152         }
18153
18154         if (!app.persistent || app.isolated) {
18155             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18156                     "Removing non-persistent process during cleanup: " + app);
18157             if (!replacingPid) {
18158                 removeProcessNameLocked(app.processName, app.uid, app);
18159             }
18160             if (mHeavyWeightProcess == app) {
18161                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18162                         mHeavyWeightProcess.userId, 0));
18163                 mHeavyWeightProcess = null;
18164             }
18165         } else if (!app.removed) {
18166             // This app is persistent, so we need to keep its record around.
18167             // If it is not already on the pending app list, add it there
18168             // and start a new process for it.
18169             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18170                 mPersistentStartingProcesses.add(app);
18171                 restart = true;
18172             }
18173         }
18174         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18175                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18176         mProcessesOnHold.remove(app);
18177
18178         if (app == mHomeProcess) {
18179             mHomeProcess = null;
18180         }
18181         if (app == mPreviousProcess) {
18182             mPreviousProcess = null;
18183         }
18184
18185         if (restart && !app.isolated) {
18186             // We have components that still need to be running in the
18187             // process, so re-launch it.
18188             if (index < 0) {
18189                 ProcessList.remove(app.pid);
18190             }
18191             addProcessNameLocked(app);
18192             startProcessLocked(app, "restart", app.processName);
18193             return true;
18194         } else if (app.pid > 0 && app.pid != MY_PID) {
18195             // Goodbye!
18196             boolean removed;
18197             synchronized (mPidsSelfLocked) {
18198                 mPidsSelfLocked.remove(app.pid);
18199                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18200             }
18201             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18202             if (app.isolated) {
18203                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18204             }
18205             app.setPid(0);
18206         }
18207         return false;
18208     }
18209
18210     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18211         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18212             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18213             if (cpr.launchingApp == app) {
18214                 return true;
18215             }
18216         }
18217         return false;
18218     }
18219
18220     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18221         // Look through the content providers we are waiting to have launched,
18222         // and if any run in this process then either schedule a restart of
18223         // the process or kill the client waiting for it if this process has
18224         // gone bad.
18225         boolean restart = false;
18226         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18227             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18228             if (cpr.launchingApp == app) {
18229                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18230                     restart = true;
18231                 } else {
18232                     removeDyingProviderLocked(app, cpr, true);
18233                 }
18234             }
18235         }
18236         return restart;
18237     }
18238
18239     // =========================================================
18240     // SERVICES
18241     // =========================================================
18242
18243     @Override
18244     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18245             int flags) {
18246         enforceNotIsolatedCaller("getServices");
18247
18248         final int callingUid = Binder.getCallingUid();
18249         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18250             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18251         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18252             callingUid);
18253         synchronized (this) {
18254             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18255                 allowed, canInteractAcrossUsers);
18256         }
18257     }
18258
18259     @Override
18260     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18261         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18262         synchronized (this) {
18263             return mServices.getRunningServiceControlPanelLocked(name);
18264         }
18265     }
18266
18267     @Override
18268     public ComponentName startService(IApplicationThread caller, Intent service,
18269             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18270             throws TransactionTooLargeException {
18271         enforceNotIsolatedCaller("startService");
18272         // Refuse possible leaked file descriptors
18273         if (service != null && service.hasFileDescriptors() == true) {
18274             throw new IllegalArgumentException("File descriptors passed in Intent");
18275         }
18276
18277         if (callingPackage == null) {
18278             throw new IllegalArgumentException("callingPackage cannot be null");
18279         }
18280
18281         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18282                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18283         synchronized(this) {
18284             final int callingPid = Binder.getCallingPid();
18285             final int callingUid = Binder.getCallingUid();
18286             final long origId = Binder.clearCallingIdentity();
18287             ComponentName res;
18288             try {
18289                 res = mServices.startServiceLocked(caller, service,
18290                         resolvedType, callingPid, callingUid,
18291                         requireForeground, callingPackage, userId);
18292             } finally {
18293                 Binder.restoreCallingIdentity(origId);
18294             }
18295             return res;
18296         }
18297     }
18298
18299     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18300             boolean fgRequired, String callingPackage, int userId)
18301             throws TransactionTooLargeException {
18302         synchronized(this) {
18303             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18304                     "startServiceInPackage: " + service + " type=" + resolvedType);
18305             final long origId = Binder.clearCallingIdentity();
18306             ComponentName res;
18307             try {
18308                 res = mServices.startServiceLocked(null, service,
18309                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18310             } finally {
18311                 Binder.restoreCallingIdentity(origId);
18312             }
18313             return res;
18314         }
18315     }
18316
18317     @Override
18318     public int stopService(IApplicationThread caller, Intent service,
18319             String resolvedType, int userId) {
18320         enforceNotIsolatedCaller("stopService");
18321         // Refuse possible leaked file descriptors
18322         if (service != null && service.hasFileDescriptors() == true) {
18323             throw new IllegalArgumentException("File descriptors passed in Intent");
18324         }
18325
18326         synchronized(this) {
18327             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18328         }
18329     }
18330
18331     @Override
18332     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18333         enforceNotIsolatedCaller("peekService");
18334         // Refuse possible leaked file descriptors
18335         if (service != null && service.hasFileDescriptors() == true) {
18336             throw new IllegalArgumentException("File descriptors passed in Intent");
18337         }
18338
18339         if (callingPackage == null) {
18340             throw new IllegalArgumentException("callingPackage cannot be null");
18341         }
18342
18343         synchronized(this) {
18344             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18345         }
18346     }
18347
18348     @Override
18349     public boolean stopServiceToken(ComponentName className, IBinder token,
18350             int startId) {
18351         synchronized(this) {
18352             return mServices.stopServiceTokenLocked(className, token, startId);
18353         }
18354     }
18355
18356     @Override
18357     public void setServiceForeground(ComponentName className, IBinder token,
18358             int id, Notification notification, int flags) {
18359         synchronized(this) {
18360             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18361         }
18362     }
18363
18364     @Override
18365     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18366             boolean requireFull, String name, String callerPackage) {
18367         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18368                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18369     }
18370
18371     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18372             String className, int flags) {
18373         boolean result = false;
18374         // For apps that don't have pre-defined UIDs, check for permission
18375         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18376             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18377                 if (ActivityManager.checkUidPermission(
18378                         INTERACT_ACROSS_USERS,
18379                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18380                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18381                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18382                             + " requests FLAG_SINGLE_USER, but app does not hold "
18383                             + INTERACT_ACROSS_USERS;
18384                     Slog.w(TAG, msg);
18385                     throw new SecurityException(msg);
18386                 }
18387                 // Permission passed
18388                 result = true;
18389             }
18390         } else if ("system".equals(componentProcessName)) {
18391             result = true;
18392         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18393             // Phone app and persistent apps are allowed to export singleuser providers.
18394             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18395                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18396         }
18397         if (DEBUG_MU) Slog.v(TAG_MU,
18398                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18399                 + Integer.toHexString(flags) + ") = " + result);
18400         return result;
18401     }
18402
18403     /**
18404      * Checks to see if the caller is in the same app as the singleton
18405      * component, or the component is in a special app. It allows special apps
18406      * to export singleton components but prevents exporting singleton
18407      * components for regular apps.
18408      */
18409     boolean isValidSingletonCall(int callingUid, int componentUid) {
18410         int componentAppId = UserHandle.getAppId(componentUid);
18411         return UserHandle.isSameApp(callingUid, componentUid)
18412                 || componentAppId == SYSTEM_UID
18413                 || componentAppId == PHONE_UID
18414                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18415                         == PackageManager.PERMISSION_GRANTED;
18416     }
18417
18418     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18419             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18420             int userId) throws TransactionTooLargeException {
18421         enforceNotIsolatedCaller("bindService");
18422
18423         // Refuse possible leaked file descriptors
18424         if (service != null && service.hasFileDescriptors() == true) {
18425             throw new IllegalArgumentException("File descriptors passed in Intent");
18426         }
18427
18428         if (callingPackage == null) {
18429             throw new IllegalArgumentException("callingPackage cannot be null");
18430         }
18431
18432         synchronized(this) {
18433             return mServices.bindServiceLocked(caller, token, service,
18434                     resolvedType, connection, flags, callingPackage, userId);
18435         }
18436     }
18437
18438     public boolean unbindService(IServiceConnection connection) {
18439         synchronized (this) {
18440             return mServices.unbindServiceLocked(connection);
18441         }
18442     }
18443
18444     public void publishService(IBinder token, Intent intent, IBinder service) {
18445         // Refuse possible leaked file descriptors
18446         if (intent != null && intent.hasFileDescriptors() == true) {
18447             throw new IllegalArgumentException("File descriptors passed in Intent");
18448         }
18449
18450         synchronized(this) {
18451             if (!(token instanceof ServiceRecord)) {
18452                 throw new IllegalArgumentException("Invalid service token");
18453             }
18454             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18455         }
18456     }
18457
18458     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18459         // Refuse possible leaked file descriptors
18460         if (intent != null && intent.hasFileDescriptors() == true) {
18461             throw new IllegalArgumentException("File descriptors passed in Intent");
18462         }
18463
18464         synchronized(this) {
18465             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18466         }
18467     }
18468
18469     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18470         synchronized(this) {
18471             if (!(token instanceof ServiceRecord)) {
18472                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18473                 throw new IllegalArgumentException("Invalid service token");
18474             }
18475             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18476         }
18477     }
18478
18479     // =========================================================
18480     // BACKUP AND RESTORE
18481     // =========================================================
18482
18483     // Cause the target app to be launched if necessary and its backup agent
18484     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18485     // activity manager to announce its creation.
18486     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18487         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18488         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18489
18490         IPackageManager pm = AppGlobals.getPackageManager();
18491         ApplicationInfo app = null;
18492         try {
18493             app = pm.getApplicationInfo(packageName, 0, userId);
18494         } catch (RemoteException e) {
18495             // can't happen; package manager is process-local
18496         }
18497         if (app == null) {
18498             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18499             return false;
18500         }
18501
18502         int oldBackupUid;
18503         int newBackupUid;
18504
18505         synchronized(this) {
18506             // !!! TODO: currently no check here that we're already bound
18507             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18508             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18509             synchronized (stats) {
18510                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18511             }
18512
18513             // Backup agent is now in use, its package can't be stopped.
18514             try {
18515                 AppGlobals.getPackageManager().setPackageStoppedState(
18516                         app.packageName, false, UserHandle.getUserId(app.uid));
18517             } catch (RemoteException e) {
18518             } catch (IllegalArgumentException e) {
18519                 Slog.w(TAG, "Failed trying to unstop package "
18520                         + app.packageName + ": " + e);
18521             }
18522
18523             BackupRecord r = new BackupRecord(ss, app, backupMode);
18524             ComponentName hostingName =
18525                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18526                             ? new ComponentName(app.packageName, app.backupAgentName)
18527                             : new ComponentName("android", "FullBackupAgent");
18528             // startProcessLocked() returns existing proc's record if it's already running
18529             ProcessRecord proc = startProcessLocked(app.processName, app,
18530                     false, 0, "backup", hostingName, false, false, false);
18531             if (proc == null) {
18532                 Slog.e(TAG, "Unable to start backup agent process " + r);
18533                 return false;
18534             }
18535
18536             // If the app is a regular app (uid >= 10000) and not the system server or phone
18537             // process, etc, then mark it as being in full backup so that certain calls to the
18538             // process can be blocked. This is not reset to false anywhere because we kill the
18539             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18540             if (UserHandle.isApp(app.uid) &&
18541                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18542                 proc.inFullBackup = true;
18543             }
18544             r.app = proc;
18545             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18546             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18547             mBackupTarget = r;
18548             mBackupAppName = app.packageName;
18549
18550             // Try not to kill the process during backup
18551             updateOomAdjLocked(proc, true);
18552
18553             // If the process is already attached, schedule the creation of the backup agent now.
18554             // If it is not yet live, this will be done when it attaches to the framework.
18555             if (proc.thread != null) {
18556                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18557                 try {
18558                     proc.thread.scheduleCreateBackupAgent(app,
18559                             compatibilityInfoForPackageLocked(app), backupMode);
18560                 } catch (RemoteException e) {
18561                     // Will time out on the backup manager side
18562                 }
18563             } else {
18564                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18565             }
18566             // Invariants: at this point, the target app process exists and the application
18567             // is either already running or in the process of coming up.  mBackupTarget and
18568             // mBackupAppName describe the app, so that when it binds back to the AM we
18569             // know that it's scheduled for a backup-agent operation.
18570         }
18571
18572         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18573         if (oldBackupUid != -1) {
18574             js.removeBackingUpUid(oldBackupUid);
18575         }
18576         if (newBackupUid != -1) {
18577             js.addBackingUpUid(newBackupUid);
18578         }
18579
18580         return true;
18581     }
18582
18583     @Override
18584     public void clearPendingBackup() {
18585         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18586         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18587
18588         synchronized (this) {
18589             mBackupTarget = null;
18590             mBackupAppName = null;
18591         }
18592
18593         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18594         js.clearAllBackingUpUids();
18595     }
18596
18597     // A backup agent has just come up
18598     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18599         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18600                 + " = " + agent);
18601
18602         synchronized(this) {
18603             if (!agentPackageName.equals(mBackupAppName)) {
18604                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18605                 return;
18606             }
18607         }
18608
18609         long oldIdent = Binder.clearCallingIdentity();
18610         try {
18611             IBackupManager bm = IBackupManager.Stub.asInterface(
18612                     ServiceManager.getService(Context.BACKUP_SERVICE));
18613             bm.agentConnected(agentPackageName, agent);
18614         } catch (RemoteException e) {
18615             // can't happen; the backup manager service is local
18616         } catch (Exception e) {
18617             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18618             e.printStackTrace();
18619         } finally {
18620             Binder.restoreCallingIdentity(oldIdent);
18621         }
18622     }
18623
18624     // done with this agent
18625     public void unbindBackupAgent(ApplicationInfo appInfo) {
18626         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18627         if (appInfo == null) {
18628             Slog.w(TAG, "unbind backup agent for null app");
18629             return;
18630         }
18631
18632         int oldBackupUid;
18633
18634         synchronized(this) {
18635             try {
18636                 if (mBackupAppName == null) {
18637                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18638                     return;
18639                 }
18640
18641                 if (!mBackupAppName.equals(appInfo.packageName)) {
18642                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18643                     return;
18644                 }
18645
18646                 // Not backing this app up any more; reset its OOM adjustment
18647                 final ProcessRecord proc = mBackupTarget.app;
18648                 updateOomAdjLocked(proc, true);
18649                 proc.inFullBackup = false;
18650
18651                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18652
18653                 // If the app crashed during backup, 'thread' will be null here
18654                 if (proc.thread != null) {
18655                     try {
18656                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18657                                 compatibilityInfoForPackageLocked(appInfo));
18658                     } catch (Exception e) {
18659                         Slog.e(TAG, "Exception when unbinding backup agent:");
18660                         e.printStackTrace();
18661                     }
18662                 }
18663             } finally {
18664                 mBackupTarget = null;
18665                 mBackupAppName = null;
18666             }
18667         }
18668
18669         if (oldBackupUid != -1) {
18670             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18671             js.removeBackingUpUid(oldBackupUid);
18672         }
18673     }
18674
18675     // =========================================================
18676     // BROADCASTS
18677     // =========================================================
18678
18679     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18680         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18681             return false;
18682         }
18683         // Easy case -- we have the app's ProcessRecord.
18684         if (record != null) {
18685             return record.info.isInstantApp();
18686         }
18687         // Otherwise check with PackageManager.
18688         if (callerPackage == null) {
18689             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18690             throw new IllegalArgumentException("Calling application did not provide package name");
18691         }
18692         mAppOpsService.checkPackage(uid, callerPackage);
18693         try {
18694             IPackageManager pm = AppGlobals.getPackageManager();
18695             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18696         } catch (RemoteException e) {
18697             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18698             return true;
18699         }
18700     }
18701
18702     boolean isPendingBroadcastProcessLocked(int pid) {
18703         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18704                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18705     }
18706
18707     void skipPendingBroadcastLocked(int pid) {
18708             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18709             for (BroadcastQueue queue : mBroadcastQueues) {
18710                 queue.skipPendingBroadcastLocked(pid);
18711             }
18712     }
18713
18714     // The app just attached; send any pending broadcasts that it should receive
18715     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18716         boolean didSomething = false;
18717         for (BroadcastQueue queue : mBroadcastQueues) {
18718             didSomething |= queue.sendPendingBroadcastsLocked(app);
18719         }
18720         return didSomething;
18721     }
18722
18723     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18724             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18725             int flags) {
18726         enforceNotIsolatedCaller("registerReceiver");
18727         ArrayList<Intent> stickyIntents = null;
18728         ProcessRecord callerApp = null;
18729         final boolean visibleToInstantApps
18730                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18731         int callingUid;
18732         int callingPid;
18733         boolean instantApp;
18734         synchronized(this) {
18735             if (caller != null) {
18736                 callerApp = getRecordForAppLocked(caller);
18737                 if (callerApp == null) {
18738                     throw new SecurityException(
18739                             "Unable to find app for caller " + caller
18740                             + " (pid=" + Binder.getCallingPid()
18741                             + ") when registering receiver " + receiver);
18742                 }
18743                 if (callerApp.info.uid != SYSTEM_UID &&
18744                         !callerApp.pkgList.containsKey(callerPackage) &&
18745                         !"android".equals(callerPackage)) {
18746                     throw new SecurityException("Given caller package " + callerPackage
18747                             + " is not running in process " + callerApp);
18748                 }
18749                 callingUid = callerApp.info.uid;
18750                 callingPid = callerApp.pid;
18751             } else {
18752                 callerPackage = null;
18753                 callingUid = Binder.getCallingUid();
18754                 callingPid = Binder.getCallingPid();
18755             }
18756
18757             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18758             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18759                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18760
18761             Iterator<String> actions = filter.actionsIterator();
18762             if (actions == null) {
18763                 ArrayList<String> noAction = new ArrayList<String>(1);
18764                 noAction.add(null);
18765                 actions = noAction.iterator();
18766             }
18767
18768             // Collect stickies of users
18769             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18770             while (actions.hasNext()) {
18771                 String action = actions.next();
18772                 for (int id : userIds) {
18773                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18774                     if (stickies != null) {
18775                         ArrayList<Intent> intents = stickies.get(action);
18776                         if (intents != null) {
18777                             if (stickyIntents == null) {
18778                                 stickyIntents = new ArrayList<Intent>();
18779                             }
18780                             stickyIntents.addAll(intents);
18781                         }
18782                     }
18783                 }
18784             }
18785         }
18786
18787         ArrayList<Intent> allSticky = null;
18788         if (stickyIntents != null) {
18789             final ContentResolver resolver = mContext.getContentResolver();
18790             // Look for any matching sticky broadcasts...
18791             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18792                 Intent intent = stickyIntents.get(i);
18793                 // Don't provided intents that aren't available to instant apps.
18794                 if (instantApp &&
18795                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18796                     continue;
18797                 }
18798                 // If intent has scheme "content", it will need to acccess
18799                 // provider that needs to lock mProviderMap in ActivityThread
18800                 // and also it may need to wait application response, so we
18801                 // cannot lock ActivityManagerService here.
18802                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18803                     if (allSticky == null) {
18804                         allSticky = new ArrayList<Intent>();
18805                     }
18806                     allSticky.add(intent);
18807                 }
18808             }
18809         }
18810
18811         // The first sticky in the list is returned directly back to the client.
18812         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18813         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18814         if (receiver == null) {
18815             return sticky;
18816         }
18817
18818         synchronized (this) {
18819             if (callerApp != null && (callerApp.thread == null
18820                     || callerApp.thread.asBinder() != caller.asBinder())) {
18821                 // Original caller already died
18822                 return null;
18823             }
18824             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18825             if (rl == null) {
18826                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18827                         userId, receiver);
18828                 if (rl.app != null) {
18829                     rl.app.receivers.add(rl);
18830                 } else {
18831                     try {
18832                         receiver.asBinder().linkToDeath(rl, 0);
18833                     } catch (RemoteException e) {
18834                         return sticky;
18835                     }
18836                     rl.linkedToDeath = true;
18837                 }
18838                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18839             } else if (rl.uid != callingUid) {
18840                 throw new IllegalArgumentException(
18841                         "Receiver requested to register for uid " + callingUid
18842                         + " was previously registered for uid " + rl.uid
18843                         + " callerPackage is " + callerPackage);
18844             } else if (rl.pid != callingPid) {
18845                 throw new IllegalArgumentException(
18846                         "Receiver requested to register for pid " + callingPid
18847                         + " was previously registered for pid " + rl.pid
18848                         + " callerPackage is " + callerPackage);
18849             } else if (rl.userId != userId) {
18850                 throw new IllegalArgumentException(
18851                         "Receiver requested to register for user " + userId
18852                         + " was previously registered for user " + rl.userId
18853                         + " callerPackage is " + callerPackage);
18854             }
18855             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18856                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18857             rl.add(bf);
18858             if (!bf.debugCheck()) {
18859                 Slog.w(TAG, "==> For Dynamic broadcast");
18860             }
18861             mReceiverResolver.addFilter(bf);
18862
18863             // Enqueue broadcasts for all existing stickies that match
18864             // this filter.
18865             if (allSticky != null) {
18866                 ArrayList receivers = new ArrayList();
18867                 receivers.add(bf);
18868
18869                 final int stickyCount = allSticky.size();
18870                 for (int i = 0; i < stickyCount; i++) {
18871                     Intent intent = allSticky.get(i);
18872                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18873                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18874                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18875                             null, 0, null, null, false, true, true, -1);
18876                     queue.enqueueParallelBroadcastLocked(r);
18877                     queue.scheduleBroadcastsLocked();
18878                 }
18879             }
18880
18881             return sticky;
18882         }
18883     }
18884
18885     public void unregisterReceiver(IIntentReceiver receiver) {
18886         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18887
18888         final long origId = Binder.clearCallingIdentity();
18889         try {
18890             boolean doTrim = false;
18891
18892             synchronized(this) {
18893                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18894                 if (rl != null) {
18895                     final BroadcastRecord r = rl.curBroadcast;
18896                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18897                         final boolean doNext = r.queue.finishReceiverLocked(
18898                                 r, r.resultCode, r.resultData, r.resultExtras,
18899                                 r.resultAbort, false);
18900                         if (doNext) {
18901                             doTrim = true;
18902                             r.queue.processNextBroadcast(false);
18903                         }
18904                     }
18905
18906                     if (rl.app != null) {
18907                         rl.app.receivers.remove(rl);
18908                     }
18909                     removeReceiverLocked(rl);
18910                     if (rl.linkedToDeath) {
18911                         rl.linkedToDeath = false;
18912                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18913                     }
18914                 }
18915             }
18916
18917             // If we actually concluded any broadcasts, we might now be able
18918             // to trim the recipients' apps from our working set
18919             if (doTrim) {
18920                 trimApplications();
18921                 return;
18922             }
18923
18924         } finally {
18925             Binder.restoreCallingIdentity(origId);
18926         }
18927     }
18928
18929     void removeReceiverLocked(ReceiverList rl) {
18930         mRegisteredReceivers.remove(rl.receiver.asBinder());
18931         for (int i = rl.size() - 1; i >= 0; i--) {
18932             mReceiverResolver.removeFilter(rl.get(i));
18933         }
18934     }
18935
18936     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18937         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18938             ProcessRecord r = mLruProcesses.get(i);
18939             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18940                 try {
18941                     r.thread.dispatchPackageBroadcast(cmd, packages);
18942                 } catch (RemoteException ex) {
18943                 }
18944             }
18945         }
18946     }
18947
18948     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18949             int callingUid, int[] users) {
18950         // TODO: come back and remove this assumption to triage all broadcasts
18951         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18952
18953         List<ResolveInfo> receivers = null;
18954         try {
18955             HashSet<ComponentName> singleUserReceivers = null;
18956             boolean scannedFirstReceivers = false;
18957             for (int user : users) {
18958                 // Skip users that have Shell restrictions, with exception of always permitted
18959                 // Shell broadcasts
18960                 if (callingUid == SHELL_UID
18961                         && mUserController.hasUserRestriction(
18962                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18963                         && !isPermittedShellBroadcast(intent)) {
18964                     continue;
18965                 }
18966                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18967                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18968                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18969                     // If this is not the system user, we need to check for
18970                     // any receivers that should be filtered out.
18971                     for (int i=0; i<newReceivers.size(); i++) {
18972                         ResolveInfo ri = newReceivers.get(i);
18973                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18974                             newReceivers.remove(i);
18975                             i--;
18976                         }
18977                     }
18978                 }
18979                 if (newReceivers != null && newReceivers.size() == 0) {
18980                     newReceivers = null;
18981                 }
18982                 if (receivers == null) {
18983                     receivers = newReceivers;
18984                 } else if (newReceivers != null) {
18985                     // We need to concatenate the additional receivers
18986                     // found with what we have do far.  This would be easy,
18987                     // but we also need to de-dup any receivers that are
18988                     // singleUser.
18989                     if (!scannedFirstReceivers) {
18990                         // Collect any single user receivers we had already retrieved.
18991                         scannedFirstReceivers = true;
18992                         for (int i=0; i<receivers.size(); i++) {
18993                             ResolveInfo ri = receivers.get(i);
18994                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18995                                 ComponentName cn = new ComponentName(
18996                                         ri.activityInfo.packageName, ri.activityInfo.name);
18997                                 if (singleUserReceivers == null) {
18998                                     singleUserReceivers = new HashSet<ComponentName>();
18999                                 }
19000                                 singleUserReceivers.add(cn);
19001                             }
19002                         }
19003                     }
19004                     // Add the new results to the existing results, tracking
19005                     // and de-dupping single user receivers.
19006                     for (int i=0; i<newReceivers.size(); i++) {
19007                         ResolveInfo ri = newReceivers.get(i);
19008                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19009                             ComponentName cn = new ComponentName(
19010                                     ri.activityInfo.packageName, ri.activityInfo.name);
19011                             if (singleUserReceivers == null) {
19012                                 singleUserReceivers = new HashSet<ComponentName>();
19013                             }
19014                             if (!singleUserReceivers.contains(cn)) {
19015                                 singleUserReceivers.add(cn);
19016                                 receivers.add(ri);
19017                             }
19018                         } else {
19019                             receivers.add(ri);
19020                         }
19021                     }
19022                 }
19023             }
19024         } catch (RemoteException ex) {
19025             // pm is in same process, this will never happen.
19026         }
19027         return receivers;
19028     }
19029
19030     private boolean isPermittedShellBroadcast(Intent intent) {
19031         // remote bugreport should always be allowed to be taken
19032         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19033     }
19034
19035     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19036             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19037         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19038             // Don't yell about broadcasts sent via shell
19039             return;
19040         }
19041
19042         final String action = intent.getAction();
19043         if (isProtectedBroadcast
19044                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19045                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19046                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19047                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19048                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19049                 || Intent.ACTION_MASTER_CLEAR.equals(action)
19050                 || Intent.ACTION_FACTORY_RESET.equals(action)
19051                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19052                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19053                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19054                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19055                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19056                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19057                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19058             // Broadcast is either protected, or it's a public action that
19059             // we've relaxed, so it's fine for system internals to send.
19060             return;
19061         }
19062
19063         // This broadcast may be a problem...  but there are often system components that
19064         // want to send an internal broadcast to themselves, which is annoying to have to
19065         // explicitly list each action as a protected broadcast, so we will check for that
19066         // one safe case and allow it: an explicit broadcast, only being received by something
19067         // that has protected itself.
19068         if (receivers != null && receivers.size() > 0
19069                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19070             boolean allProtected = true;
19071             for (int i = receivers.size()-1; i >= 0; i--) {
19072                 Object target = receivers.get(i);
19073                 if (target instanceof ResolveInfo) {
19074                     ResolveInfo ri = (ResolveInfo)target;
19075                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19076                         allProtected = false;
19077                         break;
19078                     }
19079                 } else {
19080                     BroadcastFilter bf = (BroadcastFilter)target;
19081                     if (bf.requiredPermission == null) {
19082                         allProtected = false;
19083                         break;
19084                     }
19085                 }
19086             }
19087             if (allProtected) {
19088                 // All safe!
19089                 return;
19090             }
19091         }
19092
19093         // The vast majority of broadcasts sent from system internals
19094         // should be protected to avoid security holes, so yell loudly
19095         // to ensure we examine these cases.
19096         if (callerApp != null) {
19097             Log.wtf(TAG, "Sending non-protected broadcast " + action
19098                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19099                     new Throwable());
19100         } else {
19101             Log.wtf(TAG, "Sending non-protected broadcast " + action
19102                             + " from system uid " + UserHandle.formatUid(callingUid)
19103                             + " pkg " + callerPackage,
19104                     new Throwable());
19105         }
19106     }
19107
19108     final int broadcastIntentLocked(ProcessRecord callerApp,
19109             String callerPackage, Intent intent, String resolvedType,
19110             IIntentReceiver resultTo, int resultCode, String resultData,
19111             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19112             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19113         intent = new Intent(intent);
19114
19115         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19116         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19117         if (callerInstantApp) {
19118             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19119         }
19120
19121         // By default broadcasts do not go to stopped apps.
19122         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19123
19124         // If we have not finished booting, don't allow this to launch new processes.
19125         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19126             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19127         }
19128
19129         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19130                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19131                 + " ordered=" + ordered + " userid=" + userId);
19132         if ((resultTo != null) && !ordered) {
19133             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19134         }
19135
19136         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19137                 ALLOW_NON_FULL, "broadcast", callerPackage);
19138
19139         // Make sure that the user who is receiving this broadcast is running.
19140         // If not, we will just skip it. Make an exception for shutdown broadcasts
19141         // and upgrade steps.
19142
19143         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19144             if ((callingUid != SYSTEM_UID
19145                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19146                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19147                 Slog.w(TAG, "Skipping broadcast of " + intent
19148                         + ": user " + userId + " is stopped");
19149                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19150             }
19151         }
19152
19153         BroadcastOptions brOptions = null;
19154         if (bOptions != null) {
19155             brOptions = new BroadcastOptions(bOptions);
19156             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19157                 // See if the caller is allowed to do this.  Note we are checking against
19158                 // the actual real caller (not whoever provided the operation as say a
19159                 // PendingIntent), because that who is actually supplied the arguments.
19160                 if (checkComponentPermission(
19161                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19162                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19163                         != PackageManager.PERMISSION_GRANTED) {
19164                     String msg = "Permission Denial: " + intent.getAction()
19165                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19166                             + ", uid=" + callingUid + ")"
19167                             + " requires "
19168                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19169                     Slog.w(TAG, msg);
19170                     throw new SecurityException(msg);
19171                 }
19172             }
19173         }
19174
19175         // Verify that protected broadcasts are only being sent by system code,
19176         // and that system code is only sending protected broadcasts.
19177         final String action = intent.getAction();
19178         final boolean isProtectedBroadcast;
19179         try {
19180             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19181         } catch (RemoteException e) {
19182             Slog.w(TAG, "Remote exception", e);
19183             return ActivityManager.BROADCAST_SUCCESS;
19184         }
19185
19186         final boolean isCallerSystem;
19187         switch (UserHandle.getAppId(callingUid)) {
19188             case ROOT_UID:
19189             case SYSTEM_UID:
19190             case PHONE_UID:
19191             case BLUETOOTH_UID:
19192             case NFC_UID:
19193                 isCallerSystem = true;
19194                 break;
19195             default:
19196                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19197                 break;
19198         }
19199
19200         // First line security check before anything else: stop non-system apps from
19201         // sending protected broadcasts.
19202         if (!isCallerSystem) {
19203             if (isProtectedBroadcast) {
19204                 String msg = "Permission Denial: not allowed to send broadcast "
19205                         + action + " from pid="
19206                         + callingPid + ", uid=" + callingUid;
19207                 Slog.w(TAG, msg);
19208                 throw new SecurityException(msg);
19209
19210             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19211                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19212                 // Special case for compatibility: we don't want apps to send this,
19213                 // but historically it has not been protected and apps may be using it
19214                 // to poke their own app widget.  So, instead of making it protected,
19215                 // just limit it to the caller.
19216                 if (callerPackage == null) {
19217                     String msg = "Permission Denial: not allowed to send broadcast "
19218                             + action + " from unknown caller.";
19219                     Slog.w(TAG, msg);
19220                     throw new SecurityException(msg);
19221                 } else if (intent.getComponent() != null) {
19222                     // They are good enough to send to an explicit component...  verify
19223                     // it is being sent to the calling app.
19224                     if (!intent.getComponent().getPackageName().equals(
19225                             callerPackage)) {
19226                         String msg = "Permission Denial: not allowed to send broadcast "
19227                                 + action + " to "
19228                                 + intent.getComponent().getPackageName() + " from "
19229                                 + callerPackage;
19230                         Slog.w(TAG, msg);
19231                         throw new SecurityException(msg);
19232                     }
19233                 } else {
19234                     // Limit broadcast to their own package.
19235                     intent.setPackage(callerPackage);
19236                 }
19237             }
19238         }
19239
19240         if (action != null) {
19241             if (getBackgroundLaunchBroadcasts().contains(action)) {
19242                 if (DEBUG_BACKGROUND_CHECK) {
19243                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19244                 }
19245                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19246             }
19247
19248             switch (action) {
19249                 case Intent.ACTION_UID_REMOVED:
19250                 case Intent.ACTION_PACKAGE_REMOVED:
19251                 case Intent.ACTION_PACKAGE_CHANGED:
19252                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19253                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19254                 case Intent.ACTION_PACKAGES_SUSPENDED:
19255                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19256                     // Handle special intents: if this broadcast is from the package
19257                     // manager about a package being removed, we need to remove all of
19258                     // its activities from the history stack.
19259                     if (checkComponentPermission(
19260                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19261                             callingPid, callingUid, -1, true)
19262                             != PackageManager.PERMISSION_GRANTED) {
19263                         String msg = "Permission Denial: " + intent.getAction()
19264                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19265                                 + ", uid=" + callingUid + ")"
19266                                 + " requires "
19267                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19268                         Slog.w(TAG, msg);
19269                         throw new SecurityException(msg);
19270                     }
19271                     switch (action) {
19272                         case Intent.ACTION_UID_REMOVED:
19273                             final int uid = getUidFromIntent(intent);
19274                             if (uid >= 0) {
19275                                 mBatteryStatsService.removeUid(uid);
19276                                 mAppOpsService.uidRemoved(uid);
19277                             }
19278                             break;
19279                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19280                             // If resources are unavailable just force stop all those packages
19281                             // and flush the attribute cache as well.
19282                             String list[] =
19283                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19284                             if (list != null && list.length > 0) {
19285                                 for (int i = 0; i < list.length; i++) {
19286                                     forceStopPackageLocked(list[i], -1, false, true, true,
19287                                             false, false, userId, "storage unmount");
19288                                 }
19289                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19290                                 sendPackageBroadcastLocked(
19291                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19292                                         list, userId);
19293                             }
19294                             break;
19295                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19296                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19297                             break;
19298                         case Intent.ACTION_PACKAGE_REMOVED:
19299                         case Intent.ACTION_PACKAGE_CHANGED:
19300                             Uri data = intent.getData();
19301                             String ssp;
19302                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19303                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19304                                 final boolean replacing =
19305                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19306                                 final boolean killProcess =
19307                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19308                                 final boolean fullUninstall = removed && !replacing;
19309                                 if (removed) {
19310                                     if (killProcess) {
19311                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19312                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19313                                                 false, true, true, false, fullUninstall, userId,
19314                                                 removed ? "pkg removed" : "pkg changed");
19315                                     }
19316                                     final int cmd = killProcess
19317                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19318                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19319                                     sendPackageBroadcastLocked(cmd,
19320                                             new String[] {ssp}, userId);
19321                                     if (fullUninstall) {
19322                                         mAppOpsService.packageRemoved(
19323                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19324
19325                                         // Remove all permissions granted from/to this package
19326                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19327
19328                                         removeTasksByPackageNameLocked(ssp, userId);
19329
19330                                         mServices.forceStopPackageLocked(ssp, userId);
19331
19332                                         // Hide the "unsupported display" dialog if necessary.
19333                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19334                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19335                                             mUnsupportedDisplaySizeDialog.dismiss();
19336                                             mUnsupportedDisplaySizeDialog = null;
19337                                         }
19338                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19339                                         mBatteryStatsService.notePackageUninstalled(ssp);
19340                                     }
19341                                 } else {
19342                                     if (killProcess) {
19343                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19344                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19345                                                 userId, ProcessList.INVALID_ADJ,
19346                                                 false, true, true, false, "change " + ssp);
19347                                     }
19348                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19349                                             intent.getStringArrayExtra(
19350                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19351                                 }
19352                             }
19353                             break;
19354                         case Intent.ACTION_PACKAGES_SUSPENDED:
19355                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19356                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19357                                     intent.getAction());
19358                             final String[] packageNames = intent.getStringArrayExtra(
19359                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19360                             final int userHandle = intent.getIntExtra(
19361                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19362
19363                             synchronized(ActivityManagerService.this) {
19364                                 mRecentTasks.onPackagesSuspendedChanged(
19365                                         packageNames, suspended, userHandle);
19366                             }
19367                             break;
19368                     }
19369                     break;
19370                 case Intent.ACTION_PACKAGE_REPLACED:
19371                 {
19372                     final Uri data = intent.getData();
19373                     final String ssp;
19374                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19375                         ApplicationInfo aInfo = null;
19376                         try {
19377                             aInfo = AppGlobals.getPackageManager()
19378                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19379                         } catch (RemoteException ignore) {}
19380                         if (aInfo == null) {
19381                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19382                                     + " ssp=" + ssp + " data=" + data);
19383                             return ActivityManager.BROADCAST_SUCCESS;
19384                         }
19385                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19386                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19387                                 new String[] {ssp}, userId);
19388                     }
19389                     break;
19390                 }
19391                 case Intent.ACTION_PACKAGE_ADDED:
19392                 {
19393                     // Special case for adding a package: by default turn on compatibility mode.
19394                     Uri data = intent.getData();
19395                     String ssp;
19396                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19397                         final boolean replacing =
19398                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19399                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19400
19401                         try {
19402                             ApplicationInfo ai = AppGlobals.getPackageManager().
19403                                     getApplicationInfo(ssp, 0, 0);
19404                             mBatteryStatsService.notePackageInstalled(ssp,
19405                                     ai != null ? ai.versionCode : 0);
19406                         } catch (RemoteException e) {
19407                         }
19408                     }
19409                     break;
19410                 }
19411                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19412                 {
19413                     Uri data = intent.getData();
19414                     String ssp;
19415                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19416                         // Hide the "unsupported display" dialog if necessary.
19417                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19418                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19419                             mUnsupportedDisplaySizeDialog.dismiss();
19420                             mUnsupportedDisplaySizeDialog = null;
19421                         }
19422                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19423                     }
19424                     break;
19425                 }
19426                 case Intent.ACTION_TIMEZONE_CHANGED:
19427                     // If this is the time zone changed action, queue up a message that will reset
19428                     // the timezone of all currently running processes. This message will get
19429                     // queued up before the broadcast happens.
19430                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19431                     break;
19432                 case Intent.ACTION_TIME_CHANGED:
19433                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19434                     // the tri-state value it may contain and "unknown".
19435                     // For convenience we re-use the Intent extra values.
19436                     final int NO_EXTRA_VALUE_FOUND = -1;
19437                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19438                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19439                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19440                     // Only send a message if the time preference is available.
19441                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19442                         Message updateTimePreferenceMsg =
19443                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19444                                         timeFormatPreferenceMsgValue, 0);
19445                         mHandler.sendMessage(updateTimePreferenceMsg);
19446                     }
19447                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19448                     synchronized (stats) {
19449                         stats.noteCurrentTimeChangedLocked();
19450                     }
19451                     break;
19452                 case Intent.ACTION_CLEAR_DNS_CACHE:
19453                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19454                     break;
19455                 case Proxy.PROXY_CHANGE_ACTION:
19456                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19457                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19458                     break;
19459                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19460                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19461                     // In N we just turned these off; in O we are turing them back on partly,
19462                     // only for registered receivers.  This will still address the main problem
19463                     // (a spam of apps waking up when a picture is taken putting significant
19464                     // memory pressure on the system at a bad point), while still allowing apps
19465                     // that are already actively running to know about this happening.
19466                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19467                     break;
19468                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19469                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19470                     break;
19471                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19472                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19473                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19474                     Log.w(TAG, "Broadcast " + action
19475                             + " no longer supported. It will not be delivered.");
19476                     return ActivityManager.BROADCAST_SUCCESS;
19477             }
19478
19479             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19480                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19481                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19482                 final int uid = getUidFromIntent(intent);
19483                 if (uid != -1) {
19484                     final UidRecord uidRec = mActiveUids.get(uid);
19485                     if (uidRec != null) {
19486                         uidRec.updateHasInternetPermission();
19487                     }
19488                 }
19489             }
19490         }
19491
19492         // Add to the sticky list if requested.
19493         if (sticky) {
19494             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19495                     callingPid, callingUid)
19496                     != PackageManager.PERMISSION_GRANTED) {
19497                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19498                         + callingPid + ", uid=" + callingUid
19499                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19500                 Slog.w(TAG, msg);
19501                 throw new SecurityException(msg);
19502             }
19503             if (requiredPermissions != null && requiredPermissions.length > 0) {
19504                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19505                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19506                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19507             }
19508             if (intent.getComponent() != null) {
19509                 throw new SecurityException(
19510                         "Sticky broadcasts can't target a specific component");
19511             }
19512             // We use userId directly here, since the "all" target is maintained
19513             // as a separate set of sticky broadcasts.
19514             if (userId != UserHandle.USER_ALL) {
19515                 // But first, if this is not a broadcast to all users, then
19516                 // make sure it doesn't conflict with an existing broadcast to
19517                 // all users.
19518                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19519                         UserHandle.USER_ALL);
19520                 if (stickies != null) {
19521                     ArrayList<Intent> list = stickies.get(intent.getAction());
19522                     if (list != null) {
19523                         int N = list.size();
19524                         int i;
19525                         for (i=0; i<N; i++) {
19526                             if (intent.filterEquals(list.get(i))) {
19527                                 throw new IllegalArgumentException(
19528                                         "Sticky broadcast " + intent + " for user "
19529                                         + userId + " conflicts with existing global broadcast");
19530                             }
19531                         }
19532                     }
19533                 }
19534             }
19535             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19536             if (stickies == null) {
19537                 stickies = new ArrayMap<>();
19538                 mStickyBroadcasts.put(userId, stickies);
19539             }
19540             ArrayList<Intent> list = stickies.get(intent.getAction());
19541             if (list == null) {
19542                 list = new ArrayList<>();
19543                 stickies.put(intent.getAction(), list);
19544             }
19545             final int stickiesCount = list.size();
19546             int i;
19547             for (i = 0; i < stickiesCount; i++) {
19548                 if (intent.filterEquals(list.get(i))) {
19549                     // This sticky already exists, replace it.
19550                     list.set(i, new Intent(intent));
19551                     break;
19552                 }
19553             }
19554             if (i >= stickiesCount) {
19555                 list.add(new Intent(intent));
19556             }
19557         }
19558
19559         int[] users;
19560         if (userId == UserHandle.USER_ALL) {
19561             // Caller wants broadcast to go to all started users.
19562             users = mUserController.getStartedUserArrayLocked();
19563         } else {
19564             // Caller wants broadcast to go to one specific user.
19565             users = new int[] {userId};
19566         }
19567
19568         // Figure out who all will receive this broadcast.
19569         List receivers = null;
19570         List<BroadcastFilter> registeredReceivers = null;
19571         // Need to resolve the intent to interested receivers...
19572         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19573                  == 0) {
19574             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19575         }
19576         if (intent.getComponent() == null) {
19577             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19578                 // Query one target user at a time, excluding shell-restricted users
19579                 for (int i = 0; i < users.length; i++) {
19580                     if (mUserController.hasUserRestriction(
19581                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19582                         continue;
19583                     }
19584                     List<BroadcastFilter> registeredReceiversForUser =
19585                             mReceiverResolver.queryIntent(intent,
19586                                     resolvedType, false /*defaultOnly*/, users[i]);
19587                     if (registeredReceivers == null) {
19588                         registeredReceivers = registeredReceiversForUser;
19589                     } else if (registeredReceiversForUser != null) {
19590                         registeredReceivers.addAll(registeredReceiversForUser);
19591                     }
19592                 }
19593             } else {
19594                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19595                         resolvedType, false /*defaultOnly*/, userId);
19596             }
19597         }
19598
19599         final boolean replacePending =
19600                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19601
19602         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19603                 + " replacePending=" + replacePending);
19604
19605         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19606         if (!ordered && NR > 0) {
19607             // If we are not serializing this broadcast, then send the
19608             // registered receivers separately so they don't wait for the
19609             // components to be launched.
19610             if (isCallerSystem) {
19611                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19612                         isProtectedBroadcast, registeredReceivers);
19613             }
19614             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19615             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19616                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19617                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19618                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19619             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19620             final boolean replaced = replacePending
19621                     && (queue.replaceParallelBroadcastLocked(r) != null);
19622             // Note: We assume resultTo is null for non-ordered broadcasts.
19623             if (!replaced) {
19624                 queue.enqueueParallelBroadcastLocked(r);
19625                 queue.scheduleBroadcastsLocked();
19626             }
19627             registeredReceivers = null;
19628             NR = 0;
19629         }
19630
19631         // Merge into one list.
19632         int ir = 0;
19633         if (receivers != null) {
19634             // A special case for PACKAGE_ADDED: do not allow the package
19635             // being added to see this broadcast.  This prevents them from
19636             // using this as a back door to get run as soon as they are
19637             // installed.  Maybe in the future we want to have a special install
19638             // broadcast or such for apps, but we'd like to deliberately make
19639             // this decision.
19640             String skipPackages[] = null;
19641             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19642                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19643                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19644                 Uri data = intent.getData();
19645                 if (data != null) {
19646                     String pkgName = data.getSchemeSpecificPart();
19647                     if (pkgName != null) {
19648                         skipPackages = new String[] { pkgName };
19649                     }
19650                 }
19651             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19652                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19653             }
19654             if (skipPackages != null && (skipPackages.length > 0)) {
19655                 for (String skipPackage : skipPackages) {
19656                     if (skipPackage != null) {
19657                         int NT = receivers.size();
19658                         for (int it=0; it<NT; it++) {
19659                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19660                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19661                                 receivers.remove(it);
19662                                 it--;
19663                                 NT--;
19664                             }
19665                         }
19666                     }
19667                 }
19668             }
19669
19670             int NT = receivers != null ? receivers.size() : 0;
19671             int it = 0;
19672             ResolveInfo curt = null;
19673             BroadcastFilter curr = null;
19674             while (it < NT && ir < NR) {
19675                 if (curt == null) {
19676                     curt = (ResolveInfo)receivers.get(it);
19677                 }
19678                 if (curr == null) {
19679                     curr = registeredReceivers.get(ir);
19680                 }
19681                 if (curr.getPriority() >= curt.priority) {
19682                     // Insert this broadcast record into the final list.
19683                     receivers.add(it, curr);
19684                     ir++;
19685                     curr = null;
19686                     it++;
19687                     NT++;
19688                 } else {
19689                     // Skip to the next ResolveInfo in the final list.
19690                     it++;
19691                     curt = null;
19692                 }
19693             }
19694         }
19695         while (ir < NR) {
19696             if (receivers == null) {
19697                 receivers = new ArrayList();
19698             }
19699             receivers.add(registeredReceivers.get(ir));
19700             ir++;
19701         }
19702
19703         if (isCallerSystem) {
19704             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19705                     isProtectedBroadcast, receivers);
19706         }
19707
19708         if ((receivers != null && receivers.size() > 0)
19709                 || resultTo != null) {
19710             BroadcastQueue queue = broadcastQueueForIntent(intent);
19711             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19712                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19713                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19714                     resultData, resultExtras, ordered, sticky, false, userId);
19715
19716             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19717                     + ": prev had " + queue.mOrderedBroadcasts.size());
19718             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19719                     "Enqueueing broadcast " + r.intent.getAction());
19720
19721             final BroadcastRecord oldRecord =
19722                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19723             if (oldRecord != null) {
19724                 // Replaced, fire the result-to receiver.
19725                 if (oldRecord.resultTo != null) {
19726                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19727                     try {
19728                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19729                                 oldRecord.intent,
19730                                 Activity.RESULT_CANCELED, null, null,
19731                                 false, false, oldRecord.userId);
19732                     } catch (RemoteException e) {
19733                         Slog.w(TAG, "Failure ["
19734                                 + queue.mQueueName + "] sending broadcast result of "
19735                                 + intent, e);
19736
19737                     }
19738                 }
19739             } else {
19740                 queue.enqueueOrderedBroadcastLocked(r);
19741                 queue.scheduleBroadcastsLocked();
19742             }
19743         } else {
19744             // There was nobody interested in the broadcast, but we still want to record
19745             // that it happened.
19746             if (intent.getComponent() == null && intent.getPackage() == null
19747                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19748                 // This was an implicit broadcast... let's record it for posterity.
19749                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19750             }
19751         }
19752
19753         return ActivityManager.BROADCAST_SUCCESS;
19754     }
19755
19756     /**
19757      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19758      */
19759     private int getUidFromIntent(Intent intent) {
19760         if (intent == null) {
19761             return -1;
19762         }
19763         final Bundle intentExtras = intent.getExtras();
19764         return intent.hasExtra(Intent.EXTRA_UID)
19765                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19766     }
19767
19768     final void rotateBroadcastStatsIfNeededLocked() {
19769         final long now = SystemClock.elapsedRealtime();
19770         if (mCurBroadcastStats == null ||
19771                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19772             mLastBroadcastStats = mCurBroadcastStats;
19773             if (mLastBroadcastStats != null) {
19774                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19775                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19776             }
19777             mCurBroadcastStats = new BroadcastStats();
19778         }
19779     }
19780
19781     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19782             int skipCount, long dispatchTime) {
19783         rotateBroadcastStatsIfNeededLocked();
19784         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19785     }
19786
19787     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19788         rotateBroadcastStatsIfNeededLocked();
19789         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19790     }
19791
19792     final Intent verifyBroadcastLocked(Intent intent) {
19793         // Refuse possible leaked file descriptors
19794         if (intent != null && intent.hasFileDescriptors() == true) {
19795             throw new IllegalArgumentException("File descriptors passed in Intent");
19796         }
19797
19798         int flags = intent.getFlags();
19799
19800         if (!mProcessesReady) {
19801             // if the caller really truly claims to know what they're doing, go
19802             // ahead and allow the broadcast without launching any receivers
19803             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19804                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19805             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19806                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19807                         + " before boot completion");
19808                 throw new IllegalStateException("Cannot broadcast before boot completed");
19809             }
19810         }
19811
19812         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19813             throw new IllegalArgumentException(
19814                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19815         }
19816
19817         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19818             switch (Binder.getCallingUid()) {
19819                 case ROOT_UID:
19820                 case SHELL_UID:
19821                     break;
19822                 default:
19823                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19824                             + Binder.getCallingUid());
19825                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19826                     break;
19827             }
19828         }
19829
19830         return intent;
19831     }
19832
19833     public final int broadcastIntent(IApplicationThread caller,
19834             Intent intent, String resolvedType, IIntentReceiver resultTo,
19835             int resultCode, String resultData, Bundle resultExtras,
19836             String[] requiredPermissions, int appOp, Bundle bOptions,
19837             boolean serialized, boolean sticky, int userId) {
19838         enforceNotIsolatedCaller("broadcastIntent");
19839         synchronized(this) {
19840             intent = verifyBroadcastLocked(intent);
19841
19842             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19843             final int callingPid = Binder.getCallingPid();
19844             final int callingUid = Binder.getCallingUid();
19845             final long origId = Binder.clearCallingIdentity();
19846             int res = broadcastIntentLocked(callerApp,
19847                     callerApp != null ? callerApp.info.packageName : null,
19848                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19849                     requiredPermissions, appOp, bOptions, serialized, sticky,
19850                     callingPid, callingUid, userId);
19851             Binder.restoreCallingIdentity(origId);
19852             return res;
19853         }
19854     }
19855
19856
19857     int broadcastIntentInPackage(String packageName, int uid,
19858             Intent intent, String resolvedType, IIntentReceiver resultTo,
19859             int resultCode, String resultData, Bundle resultExtras,
19860             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19861             int userId) {
19862         synchronized(this) {
19863             intent = verifyBroadcastLocked(intent);
19864
19865             final long origId = Binder.clearCallingIdentity();
19866             String[] requiredPermissions = requiredPermission == null ? null
19867                     : new String[] {requiredPermission};
19868             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19869                     resultTo, resultCode, resultData, resultExtras,
19870                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19871                     sticky, -1, uid, userId);
19872             Binder.restoreCallingIdentity(origId);
19873             return res;
19874         }
19875     }
19876
19877     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19878         // Refuse possible leaked file descriptors
19879         if (intent != null && intent.hasFileDescriptors() == true) {
19880             throw new IllegalArgumentException("File descriptors passed in Intent");
19881         }
19882
19883         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19884                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19885
19886         synchronized(this) {
19887             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19888                     != PackageManager.PERMISSION_GRANTED) {
19889                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19890                         + Binder.getCallingPid()
19891                         + ", uid=" + Binder.getCallingUid()
19892                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19893                 Slog.w(TAG, msg);
19894                 throw new SecurityException(msg);
19895             }
19896             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19897             if (stickies != null) {
19898                 ArrayList<Intent> list = stickies.get(intent.getAction());
19899                 if (list != null) {
19900                     int N = list.size();
19901                     int i;
19902                     for (i=0; i<N; i++) {
19903                         if (intent.filterEquals(list.get(i))) {
19904                             list.remove(i);
19905                             break;
19906                         }
19907                     }
19908                     if (list.size() <= 0) {
19909                         stickies.remove(intent.getAction());
19910                     }
19911                 }
19912                 if (stickies.size() <= 0) {
19913                     mStickyBroadcasts.remove(userId);
19914                 }
19915             }
19916         }
19917     }
19918
19919     void backgroundServicesFinishedLocked(int userId) {
19920         for (BroadcastQueue queue : mBroadcastQueues) {
19921             queue.backgroundServicesFinishedLocked(userId);
19922         }
19923     }
19924
19925     public void finishReceiver(IBinder who, int resultCode, String resultData,
19926             Bundle resultExtras, boolean resultAbort, int flags) {
19927         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19928
19929         // Refuse possible leaked file descriptors
19930         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19931             throw new IllegalArgumentException("File descriptors passed in Bundle");
19932         }
19933
19934         final long origId = Binder.clearCallingIdentity();
19935         try {
19936             boolean doNext = false;
19937             BroadcastRecord r;
19938
19939             synchronized(this) {
19940                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19941                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19942                 r = queue.getMatchingOrderedReceiver(who);
19943                 if (r != null) {
19944                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19945                         resultData, resultExtras, resultAbort, true);
19946                 }
19947             }
19948
19949             if (doNext) {
19950                 r.queue.processNextBroadcast(false);
19951             }
19952             trimApplications();
19953         } finally {
19954             Binder.restoreCallingIdentity(origId);
19955         }
19956     }
19957
19958     // =========================================================
19959     // INSTRUMENTATION
19960     // =========================================================
19961
19962     public boolean startInstrumentation(ComponentName className,
19963             String profileFile, int flags, Bundle arguments,
19964             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19965             int userId, String abiOverride) {
19966         enforceNotIsolatedCaller("startInstrumentation");
19967         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19968                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19969         // Refuse possible leaked file descriptors
19970         if (arguments != null && arguments.hasFileDescriptors()) {
19971             throw new IllegalArgumentException("File descriptors passed in Bundle");
19972         }
19973
19974         synchronized(this) {
19975             InstrumentationInfo ii = null;
19976             ApplicationInfo ai = null;
19977             try {
19978                 ii = mContext.getPackageManager().getInstrumentationInfo(
19979                     className, STOCK_PM_FLAGS);
19980                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19981                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19982             } catch (PackageManager.NameNotFoundException e) {
19983             } catch (RemoteException e) {
19984             }
19985             if (ii == null) {
19986                 reportStartInstrumentationFailureLocked(watcher, className,
19987                         "Unable to find instrumentation info for: " + className);
19988                 return false;
19989             }
19990             if (ai == null) {
19991                 reportStartInstrumentationFailureLocked(watcher, className,
19992                         "Unable to find instrumentation target package: " + ii.targetPackage);
19993                 return false;
19994             }
19995             if (!ai.hasCode()) {
19996                 reportStartInstrumentationFailureLocked(watcher, className,
19997                         "Instrumentation target has no code: " + ii.targetPackage);
19998                 return false;
19999             }
20000
20001             int match = mContext.getPackageManager().checkSignatures(
20002                     ii.targetPackage, ii.packageName);
20003             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20004                 String msg = "Permission Denial: starting instrumentation "
20005                         + className + " from pid="
20006                         + Binder.getCallingPid()
20007                         + ", uid=" + Binder.getCallingPid()
20008                         + " not allowed because package " + ii.packageName
20009                         + " does not have a signature matching the target "
20010                         + ii.targetPackage;
20011                 reportStartInstrumentationFailureLocked(watcher, className, msg);
20012                 throw new SecurityException(msg);
20013             }
20014
20015             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20016             activeInstr.mClass = className;
20017             String defProcess = ai.processName;;
20018             if (ii.targetProcesses == null) {
20019                 activeInstr.mTargetProcesses = new String[]{ai.processName};
20020             } else if (ii.targetProcesses.equals("*")) {
20021                 activeInstr.mTargetProcesses = new String[0];
20022             } else {
20023                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20024                 defProcess = activeInstr.mTargetProcesses[0];
20025             }
20026             activeInstr.mTargetInfo = ai;
20027             activeInstr.mProfileFile = profileFile;
20028             activeInstr.mArguments = arguments;
20029             activeInstr.mWatcher = watcher;
20030             activeInstr.mUiAutomationConnection = uiAutomationConnection;
20031             activeInstr.mResultClass = className;
20032
20033             final long origId = Binder.clearCallingIdentity();
20034             // Instrumentation can kill and relaunch even persistent processes
20035             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20036                     "start instr");
20037             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20038             app.instr = activeInstr;
20039             activeInstr.mFinished = false;
20040             activeInstr.mRunningProcesses.add(app);
20041             if (!mActiveInstrumentation.contains(activeInstr)) {
20042                 mActiveInstrumentation.add(activeInstr);
20043             }
20044             Binder.restoreCallingIdentity(origId);
20045         }
20046
20047         return true;
20048     }
20049
20050     /**
20051      * Report errors that occur while attempting to start Instrumentation.  Always writes the
20052      * error to the logs, but if somebody is watching, send the report there too.  This enables
20053      * the "am" command to report errors with more information.
20054      *
20055      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20056      * @param cn The component name of the instrumentation.
20057      * @param report The error report.
20058      */
20059     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20060             ComponentName cn, String report) {
20061         Slog.w(TAG, report);
20062         if (watcher != null) {
20063             Bundle results = new Bundle();
20064             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20065             results.putString("Error", report);
20066             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20067         }
20068     }
20069
20070     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20071         if (app.instr == null) {
20072             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20073             return;
20074         }
20075
20076         if (!app.instr.mFinished && results != null) {
20077             if (app.instr.mCurResults == null) {
20078                 app.instr.mCurResults = new Bundle(results);
20079             } else {
20080                 app.instr.mCurResults.putAll(results);
20081             }
20082         }
20083     }
20084
20085     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20086         int userId = UserHandle.getCallingUserId();
20087         // Refuse possible leaked file descriptors
20088         if (results != null && results.hasFileDescriptors()) {
20089             throw new IllegalArgumentException("File descriptors passed in Intent");
20090         }
20091
20092         synchronized(this) {
20093             ProcessRecord app = getRecordForAppLocked(target);
20094             if (app == null) {
20095                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20096                 return;
20097             }
20098             final long origId = Binder.clearCallingIdentity();
20099             addInstrumentationResultsLocked(app, results);
20100             Binder.restoreCallingIdentity(origId);
20101         }
20102     }
20103
20104     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20105         if (app.instr == null) {
20106             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20107             return;
20108         }
20109
20110         if (!app.instr.mFinished) {
20111             if (app.instr.mWatcher != null) {
20112                 Bundle finalResults = app.instr.mCurResults;
20113                 if (finalResults != null) {
20114                     if (app.instr.mCurResults != null && results != null) {
20115                         finalResults.putAll(results);
20116                     }
20117                 } else {
20118                     finalResults = results;
20119                 }
20120                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20121                         app.instr.mClass, resultCode, finalResults);
20122             }
20123
20124             // Can't call out of the system process with a lock held, so post a message.
20125             if (app.instr.mUiAutomationConnection != null) {
20126                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20127                         app.instr.mUiAutomationConnection).sendToTarget();
20128             }
20129             app.instr.mFinished = true;
20130         }
20131
20132         app.instr.removeProcess(app);
20133         app.instr = null;
20134
20135         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20136                 "finished inst");
20137     }
20138
20139     public void finishInstrumentation(IApplicationThread target,
20140             int resultCode, Bundle results) {
20141         int userId = UserHandle.getCallingUserId();
20142         // Refuse possible leaked file descriptors
20143         if (results != null && results.hasFileDescriptors()) {
20144             throw new IllegalArgumentException("File descriptors passed in Intent");
20145         }
20146
20147         synchronized(this) {
20148             ProcessRecord app = getRecordForAppLocked(target);
20149             if (app == null) {
20150                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20151                 return;
20152             }
20153             final long origId = Binder.clearCallingIdentity();
20154             finishInstrumentationLocked(app, resultCode, results);
20155             Binder.restoreCallingIdentity(origId);
20156         }
20157     }
20158
20159     // =========================================================
20160     // CONFIGURATION
20161     // =========================================================
20162
20163     public ConfigurationInfo getDeviceConfigurationInfo() {
20164         ConfigurationInfo config = new ConfigurationInfo();
20165         synchronized (this) {
20166             final Configuration globalConfig = getGlobalConfiguration();
20167             config.reqTouchScreen = globalConfig.touchscreen;
20168             config.reqKeyboardType = globalConfig.keyboard;
20169             config.reqNavigation = globalConfig.navigation;
20170             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20171                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20172                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20173             }
20174             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20175                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20176                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20177             }
20178             config.reqGlEsVersion = GL_ES_VERSION;
20179         }
20180         return config;
20181     }
20182
20183     ActivityStack getFocusedStack() {
20184         return mStackSupervisor.getFocusedStack();
20185     }
20186
20187     @Override
20188     public int getFocusedStackId() throws RemoteException {
20189         ActivityStack focusedStack = getFocusedStack();
20190         if (focusedStack != null) {
20191             return focusedStack.getStackId();
20192         }
20193         return -1;
20194     }
20195
20196     public Configuration getConfiguration() {
20197         Configuration ci;
20198         synchronized(this) {
20199             ci = new Configuration(getGlobalConfiguration());
20200             ci.userSetLocale = false;
20201         }
20202         return ci;
20203     }
20204
20205     @Override
20206     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20207         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20208         synchronized (this) {
20209             mSuppressResizeConfigChanges = suppress;
20210         }
20211     }
20212
20213     /**
20214      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20215      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20216      *       activity and clearing the task at the same time.
20217      */
20218     @Override
20219     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20220         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20221         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20222             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20223         }
20224         synchronized (this) {
20225             final long origId = Binder.clearCallingIdentity();
20226             try {
20227                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20228             } finally {
20229                 Binder.restoreCallingIdentity(origId);
20230             }
20231         }
20232     }
20233
20234     @Override
20235     public void updatePersistentConfiguration(Configuration values) {
20236         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20237         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20238         if (values == null) {
20239             throw new NullPointerException("Configuration must not be null");
20240         }
20241
20242         int userId = UserHandle.getCallingUserId();
20243
20244         synchronized(this) {
20245             updatePersistentConfigurationLocked(values, userId);
20246         }
20247     }
20248
20249     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20250         final long origId = Binder.clearCallingIdentity();
20251         try {
20252             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20253         } finally {
20254             Binder.restoreCallingIdentity(origId);
20255         }
20256     }
20257
20258     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20259         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20260                 FONT_SCALE, 1.0f, userId);
20261
20262         synchronized (this) {
20263             if (getGlobalConfiguration().fontScale == scaleFactor) {
20264                 return;
20265             }
20266
20267             final Configuration configuration
20268                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20269             configuration.fontScale = scaleFactor;
20270             updatePersistentConfigurationLocked(configuration, userId);
20271         }
20272     }
20273
20274     private void enforceWriteSettingsPermission(String func) {
20275         int uid = Binder.getCallingUid();
20276         if (uid == ROOT_UID) {
20277             return;
20278         }
20279
20280         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20281                 Settings.getPackageNameForUid(mContext, uid), false)) {
20282             return;
20283         }
20284
20285         String msg = "Permission Denial: " + func + " from pid="
20286                 + Binder.getCallingPid()
20287                 + ", uid=" + uid
20288                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20289         Slog.w(TAG, msg);
20290         throw new SecurityException(msg);
20291     }
20292
20293     @Override
20294     public boolean updateConfiguration(Configuration values) {
20295         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20296
20297         synchronized(this) {
20298             if (values == null && mWindowManager != null) {
20299                 // sentinel: fetch the current configuration from the window manager
20300                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20301             }
20302
20303             if (mWindowManager != null) {
20304                 // Update OOM levels based on display size.
20305                 mProcessList.applyDisplaySize(mWindowManager);
20306             }
20307
20308             final long origId = Binder.clearCallingIdentity();
20309             try {
20310                 if (values != null) {
20311                     Settings.System.clearConfiguration(values);
20312                 }
20313                 updateConfigurationLocked(values, null, false, false /* persistent */,
20314                         UserHandle.USER_NULL, false /* deferResume */,
20315                         mTmpUpdateConfigurationResult);
20316                 return mTmpUpdateConfigurationResult.changes != 0;
20317             } finally {
20318                 Binder.restoreCallingIdentity(origId);
20319             }
20320         }
20321     }
20322
20323     void updateUserConfigurationLocked() {
20324         final Configuration configuration = new Configuration(getGlobalConfiguration());
20325         final int currentUserId = mUserController.getCurrentUserIdLocked();
20326         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20327                 currentUserId, Settings.System.canWrite(mContext));
20328         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20329                 false /* persistent */, currentUserId, false /* deferResume */);
20330     }
20331
20332     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20333             boolean initLocale) {
20334         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20335     }
20336
20337     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20338             boolean initLocale, boolean deferResume) {
20339         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20340         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20341                 UserHandle.USER_NULL, deferResume);
20342     }
20343
20344     // To cache the list of supported system locales
20345     private String[] mSupportedSystemLocales = null;
20346
20347     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20348             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20349         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20350                 deferResume, null /* result */);
20351     }
20352
20353     /**
20354      * Do either or both things: (1) change the current configuration, and (2)
20355      * make sure the given activity is running with the (now) current
20356      * configuration.  Returns true if the activity has been left running, or
20357      * false if <var>starting</var> is being destroyed to match the new
20358      * configuration.
20359      *
20360      * @param userId is only used when persistent parameter is set to true to persist configuration
20361      *               for that particular user
20362      */
20363     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20364             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20365             UpdateConfigurationResult result) {
20366         int changes = 0;
20367         boolean kept = true;
20368
20369         if (mWindowManager != null) {
20370             mWindowManager.deferSurfaceLayout();
20371         }
20372         try {
20373             if (values != null) {
20374                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20375                         deferResume);
20376             }
20377
20378             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20379         } finally {
20380             if (mWindowManager != null) {
20381                 mWindowManager.continueSurfaceLayout();
20382             }
20383         }
20384
20385         if (result != null) {
20386             result.changes = changes;
20387             result.activityRelaunched = !kept;
20388         }
20389         return kept;
20390     }
20391
20392     /** Update default (global) configuration and notify listeners about changes. */
20393     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20394             boolean persistent, int userId, boolean deferResume) {
20395         mTempConfig.setTo(getGlobalConfiguration());
20396         final int changes = mTempConfig.updateFrom(values);
20397         if (changes == 0) {
20398             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20399             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20400             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20401             // (even if there are no actual changes) to unfreeze the window.
20402             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20403             return 0;
20404         }
20405
20406         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20407                 "Updating global configuration to: " + values);
20408
20409         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20410
20411         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20412             final LocaleList locales = values.getLocales();
20413             int bestLocaleIndex = 0;
20414             if (locales.size() > 1) {
20415                 if (mSupportedSystemLocales == null) {
20416                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20417                 }
20418                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20419             }
20420             SystemProperties.set("persist.sys.locale",
20421                     locales.get(bestLocaleIndex).toLanguageTag());
20422             LocaleList.setDefault(locales, bestLocaleIndex);
20423             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20424                     locales.get(bestLocaleIndex)));
20425         }
20426
20427         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20428         mTempConfig.seq = mConfigurationSeq;
20429
20430         // Update stored global config and notify everyone about the change.
20431         mStackSupervisor.onConfigurationChanged(mTempConfig);
20432
20433         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20434         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20435         mUsageStatsService.reportConfigurationChange(mTempConfig,
20436                 mUserController.getCurrentUserIdLocked());
20437
20438         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20439         mShowDialogs = shouldShowDialogs(mTempConfig);
20440
20441         AttributeCache ac = AttributeCache.instance();
20442         if (ac != null) {
20443             ac.updateConfiguration(mTempConfig);
20444         }
20445
20446         // Make sure all resources in our process are updated right now, so that anyone who is going
20447         // to retrieve resource values after we return will be sure to get the new ones. This is
20448         // especially important during boot, where the first config change needs to guarantee all
20449         // resources have that config before following boot code is executed.
20450         mSystemThread.applyConfigurationToResources(mTempConfig);
20451
20452         // We need another copy of global config because we're scheduling some calls instead of
20453         // running them in place. We need to be sure that object we send will be handled unchanged.
20454         final Configuration configCopy = new Configuration(mTempConfig);
20455         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20456             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20457             msg.obj = configCopy;
20458             msg.arg1 = userId;
20459             mHandler.sendMessage(msg);
20460         }
20461
20462         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20463             ProcessRecord app = mLruProcesses.get(i);
20464             try {
20465                 if (app.thread != null) {
20466                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20467                             + app.processName + " new config " + configCopy);
20468                     app.thread.scheduleConfigurationChanged(configCopy);
20469                 }
20470             } catch (Exception e) {
20471             }
20472         }
20473
20474         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20475         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20476                 | Intent.FLAG_RECEIVER_FOREGROUND
20477                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20478         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20479                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20480                 UserHandle.USER_ALL);
20481         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20482             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20483             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20484                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20485                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20486             if (initLocale || !mProcessesReady) {
20487                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20488             }
20489             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20490                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20491                     UserHandle.USER_ALL);
20492         }
20493
20494         // Override configuration of the default display duplicates global config, so we need to
20495         // update it also. This will also notify WindowManager about changes.
20496         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20497                 DEFAULT_DISPLAY);
20498
20499         return changes;
20500     }
20501
20502     @Override
20503     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20504         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20505
20506         synchronized (this) {
20507             // Check if display is initialized in AM.
20508             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20509                 // Call might come when display is not yet added or has already been removed.
20510                 if (DEBUG_CONFIGURATION) {
20511                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20512                             + displayId);
20513                 }
20514                 return false;
20515             }
20516
20517             if (values == null && mWindowManager != null) {
20518                 // sentinel: fetch the current configuration from the window manager
20519                 values = mWindowManager.computeNewConfiguration(displayId);
20520             }
20521
20522             if (mWindowManager != null) {
20523                 // Update OOM levels based on display size.
20524                 mProcessList.applyDisplaySize(mWindowManager);
20525             }
20526
20527             final long origId = Binder.clearCallingIdentity();
20528             try {
20529                 if (values != null) {
20530                     Settings.System.clearConfiguration(values);
20531                 }
20532                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20533                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20534                 return mTmpUpdateConfigurationResult.changes != 0;
20535             } finally {
20536                 Binder.restoreCallingIdentity(origId);
20537             }
20538         }
20539     }
20540
20541     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20542             boolean deferResume, int displayId) {
20543         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20544                 displayId, null /* result */);
20545     }
20546
20547     /**
20548      * Updates override configuration specific for the selected display. If no config is provided,
20549      * new one will be computed in WM based on current display info.
20550      */
20551     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20552             ActivityRecord starting, boolean deferResume, int displayId,
20553             UpdateConfigurationResult result) {
20554         int changes = 0;
20555         boolean kept = true;
20556
20557         if (mWindowManager != null) {
20558             mWindowManager.deferSurfaceLayout();
20559         }
20560         try {
20561             if (values != null) {
20562                 if (displayId == DEFAULT_DISPLAY) {
20563                     // Override configuration of the default display duplicates global config, so
20564                     // we're calling global config update instead for default display. It will also
20565                     // apply the correct override config.
20566                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20567                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20568                 } else {
20569                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20570                 }
20571             }
20572
20573             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20574         } finally {
20575             if (mWindowManager != null) {
20576                 mWindowManager.continueSurfaceLayout();
20577             }
20578         }
20579
20580         if (result != null) {
20581             result.changes = changes;
20582             result.activityRelaunched = !kept;
20583         }
20584         return kept;
20585     }
20586
20587     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20588             int displayId) {
20589         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20590         final int changes = mTempConfig.updateFrom(values);
20591         if (changes != 0) {
20592             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20593                     + mTempConfig + " for displayId=" + displayId);
20594             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20595
20596             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20597             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20598                 // Reset the unsupported display size dialog.
20599                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20600
20601                 killAllBackgroundProcessesExcept(N,
20602                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20603             }
20604         }
20605
20606         // Update the configuration with WM first and check if any of the stacks need to be resized
20607         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20608         // necessary. This way we don't need to relaunch again afterwards in
20609         // ensureActivityConfigurationLocked().
20610         if (mWindowManager != null) {
20611             final int[] resizedStacks =
20612                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20613             if (resizedStacks != null) {
20614                 for (int stackId : resizedStacks) {
20615                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20616                 }
20617             }
20618         }
20619
20620         return changes;
20621     }
20622
20623     /** Applies latest configuration and/or visibility updates if needed. */
20624     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20625         boolean kept = true;
20626         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20627         // mainStack is null during startup.
20628         if (mainStack != null) {
20629             if (changes != 0 && starting == null) {
20630                 // If the configuration changed, and the caller is not already
20631                 // in the process of starting an activity, then find the top
20632                 // activity to check if its configuration needs to change.
20633                 starting = mainStack.topRunningActivityLocked();
20634             }
20635
20636             if (starting != null) {
20637                 kept = starting.ensureActivityConfigurationLocked(changes,
20638                         false /* preserveWindow */);
20639                 // And we need to make sure at this point that all other activities
20640                 // are made visible with the correct configuration.
20641                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20642                         !PRESERVE_WINDOWS);
20643             }
20644         }
20645
20646         return kept;
20647     }
20648
20649     /** Helper method that requests bounds from WM and applies them to stack. */
20650     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20651         final Rect newStackBounds = new Rect();
20652         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20653         mStackSupervisor.resizeStackLocked(
20654                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20655                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20656                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20657     }
20658
20659     /**
20660      * Decide based on the configuration whether we should show the ANR,
20661      * crash, etc dialogs.  The idea is that if there is no affordance to
20662      * press the on-screen buttons, or the user experience would be more
20663      * greatly impacted than the crash itself, we shouldn't show the dialog.
20664      *
20665      * A thought: SystemUI might also want to get told about this, the Power
20666      * dialog / global actions also might want different behaviors.
20667      */
20668     private static boolean shouldShowDialogs(Configuration config) {
20669         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20670                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20671                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20672         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20673         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20674                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20675                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20676                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20677         return inputMethodExists && uiModeSupportsDialogs;
20678     }
20679
20680     @Override
20681     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20682         synchronized (this) {
20683             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20684             if (srec != null) {
20685                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20686             }
20687         }
20688         return false;
20689     }
20690
20691     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20692             Intent resultData) {
20693
20694         synchronized (this) {
20695             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20696             if (r != null) {
20697                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20698             }
20699             return false;
20700         }
20701     }
20702
20703     public int getLaunchedFromUid(IBinder activityToken) {
20704         ActivityRecord srec;
20705         synchronized (this) {
20706             srec = ActivityRecord.forTokenLocked(activityToken);
20707         }
20708         if (srec == null) {
20709             return -1;
20710         }
20711         return srec.launchedFromUid;
20712     }
20713
20714     public String getLaunchedFromPackage(IBinder activityToken) {
20715         ActivityRecord srec;
20716         synchronized (this) {
20717             srec = ActivityRecord.forTokenLocked(activityToken);
20718         }
20719         if (srec == null) {
20720             return null;
20721         }
20722         return srec.launchedFromPackage;
20723     }
20724
20725     // =========================================================
20726     // LIFETIME MANAGEMENT
20727     // =========================================================
20728
20729     // Returns whether the app is receiving broadcast.
20730     // If receiving, fetch all broadcast queues which the app is
20731     // the current [or imminent] receiver on.
20732     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20733             ArraySet<BroadcastQueue> receivingQueues) {
20734         if (!app.curReceivers.isEmpty()) {
20735             for (BroadcastRecord r : app.curReceivers) {
20736                 receivingQueues.add(r.queue);
20737             }
20738             return true;
20739         }
20740
20741         // It's not the current receiver, but it might be starting up to become one
20742         for (BroadcastQueue queue : mBroadcastQueues) {
20743             final BroadcastRecord r = queue.mPendingBroadcast;
20744             if (r != null && r.curApp == app) {
20745                 // found it; report which queue it's in
20746                 receivingQueues.add(queue);
20747             }
20748         }
20749
20750         return !receivingQueues.isEmpty();
20751     }
20752
20753     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20754             int targetUid, ComponentName targetComponent, String targetProcess) {
20755         if (!mTrackingAssociations) {
20756             return null;
20757         }
20758         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20759                 = mAssociations.get(targetUid);
20760         if (components == null) {
20761             components = new ArrayMap<>();
20762             mAssociations.put(targetUid, components);
20763         }
20764         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20765         if (sourceUids == null) {
20766             sourceUids = new SparseArray<>();
20767             components.put(targetComponent, sourceUids);
20768         }
20769         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20770         if (sourceProcesses == null) {
20771             sourceProcesses = new ArrayMap<>();
20772             sourceUids.put(sourceUid, sourceProcesses);
20773         }
20774         Association ass = sourceProcesses.get(sourceProcess);
20775         if (ass == null) {
20776             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20777                     targetProcess);
20778             sourceProcesses.put(sourceProcess, ass);
20779         }
20780         ass.mCount++;
20781         ass.mNesting++;
20782         if (ass.mNesting == 1) {
20783             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20784             ass.mLastState = sourceState;
20785         }
20786         return ass;
20787     }
20788
20789     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20790             ComponentName targetComponent) {
20791         if (!mTrackingAssociations) {
20792             return;
20793         }
20794         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20795                 = mAssociations.get(targetUid);
20796         if (components == null) {
20797             return;
20798         }
20799         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20800         if (sourceUids == null) {
20801             return;
20802         }
20803         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20804         if (sourceProcesses == null) {
20805             return;
20806         }
20807         Association ass = sourceProcesses.get(sourceProcess);
20808         if (ass == null || ass.mNesting <= 0) {
20809             return;
20810         }
20811         ass.mNesting--;
20812         if (ass.mNesting == 0) {
20813             long uptime = SystemClock.uptimeMillis();
20814             ass.mTime += uptime - ass.mStartTime;
20815             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20816                     += uptime - ass.mLastStateUptime;
20817             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20818         }
20819     }
20820
20821     private void noteUidProcessState(final int uid, final int state) {
20822         mBatteryStatsService.noteUidProcessState(uid, state);
20823         if (mTrackingAssociations) {
20824             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20825                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20826                         = mAssociations.valueAt(i1);
20827                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20828                     SparseArray<ArrayMap<String, Association>> sourceUids
20829                             = targetComponents.valueAt(i2);
20830                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20831                     if (sourceProcesses != null) {
20832                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20833                             Association ass = sourceProcesses.valueAt(i4);
20834                             if (ass.mNesting >= 1) {
20835                                 // currently associated
20836                                 long uptime = SystemClock.uptimeMillis();
20837                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20838                                         += uptime - ass.mLastStateUptime;
20839                                 ass.mLastState = state;
20840                                 ass.mLastStateUptime = uptime;
20841                             }
20842                         }
20843                     }
20844                 }
20845             }
20846         }
20847     }
20848
20849     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20850             boolean doingAll, long now) {
20851         if (mAdjSeq == app.adjSeq) {
20852             // This adjustment has already been computed.
20853             return app.curRawAdj;
20854         }
20855
20856         if (app.thread == null) {
20857             app.adjSeq = mAdjSeq;
20858             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20859             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20860             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20861         }
20862
20863         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20864         app.adjSource = null;
20865         app.adjTarget = null;
20866         app.empty = false;
20867         app.cached = false;
20868
20869         final int activitiesSize = app.activities.size();
20870
20871         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20872             // The max adjustment doesn't allow this app to be anything
20873             // below foreground, so it is not worth doing work for it.
20874             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20875             app.adjType = "fixed";
20876             app.adjSeq = mAdjSeq;
20877             app.curRawAdj = app.maxAdj;
20878             app.foregroundActivities = false;
20879             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20880             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20881             // System processes can do UI, and when they do we want to have
20882             // them trim their memory after the user leaves the UI.  To
20883             // facilitate this, here we need to determine whether or not it
20884             // is currently showing UI.
20885             app.systemNoUi = true;
20886             if (app == TOP_APP) {
20887                 app.systemNoUi = false;
20888                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20889                 app.adjType = "pers-top-activity";
20890             } else if (app.hasTopUi) {
20891                 app.systemNoUi = false;
20892                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20893                 app.adjType = "pers-top-ui";
20894             } else if (activitiesSize > 0) {
20895                 for (int j = 0; j < activitiesSize; j++) {
20896                     final ActivityRecord r = app.activities.get(j);
20897                     if (r.visible) {
20898                         app.systemNoUi = false;
20899                     }
20900                 }
20901             }
20902             if (!app.systemNoUi) {
20903                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20904             }
20905             return (app.curAdj=app.maxAdj);
20906         }
20907
20908         app.systemNoUi = false;
20909
20910         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20911
20912         // Determine the importance of the process, starting with most
20913         // important to least, and assign an appropriate OOM adjustment.
20914         int adj;
20915         int schedGroup;
20916         int procState;
20917         boolean foregroundActivities = false;
20918         mTmpBroadcastQueue.clear();
20919         if (app == TOP_APP) {
20920             // The last app on the list is the foreground app.
20921             adj = ProcessList.FOREGROUND_APP_ADJ;
20922             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20923             app.adjType = "top-activity";
20924             foregroundActivities = true;
20925             procState = PROCESS_STATE_CUR_TOP;
20926             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20927         } else if (app.instr != null) {
20928             // Don't want to kill running instrumentation.
20929             adj = ProcessList.FOREGROUND_APP_ADJ;
20930             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20931             app.adjType = "instrumentation";
20932             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20933             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20934         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20935             // An app that is currently receiving a broadcast also
20936             // counts as being in the foreground for OOM killer purposes.
20937             // It's placed in a sched group based on the nature of the
20938             // broadcast as reflected by which queue it's active in.
20939             adj = ProcessList.FOREGROUND_APP_ADJ;
20940             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20941                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20942             app.adjType = "broadcast";
20943             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20944             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20945         } else if (app.executingServices.size() > 0) {
20946             // An app that is currently executing a service callback also
20947             // counts as being in the foreground.
20948             adj = ProcessList.FOREGROUND_APP_ADJ;
20949             schedGroup = app.execServicesFg ?
20950                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20951             app.adjType = "exec-service";
20952             procState = ActivityManager.PROCESS_STATE_SERVICE;
20953             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20954             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20955         } else {
20956             // As far as we know the process is empty.  We may change our mind later.
20957             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20958             // At this point we don't actually know the adjustment.  Use the cached adj
20959             // value that the caller wants us to.
20960             adj = cachedAdj;
20961             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20962             app.cached = true;
20963             app.empty = true;
20964             app.adjType = "cch-empty";
20965             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20966         }
20967
20968         // Examine all activities if not already foreground.
20969         if (!foregroundActivities && activitiesSize > 0) {
20970             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20971             for (int j = 0; j < activitiesSize; j++) {
20972                 final ActivityRecord r = app.activities.get(j);
20973                 if (r.app != app) {
20974                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20975                             + " instead of expected " + app);
20976                     if (r.app == null || (r.app.uid == app.uid)) {
20977                         // Only fix things up when they look sane
20978                         r.app = app;
20979                     } else {
20980                         continue;
20981                     }
20982                 }
20983                 if (r.visible) {
20984                     // App has a visible activity; only upgrade adjustment.
20985                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20986                         adj = ProcessList.VISIBLE_APP_ADJ;
20987                         app.adjType = "vis-activity";
20988                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20989                     }
20990                     if (procState > PROCESS_STATE_CUR_TOP) {
20991                         procState = PROCESS_STATE_CUR_TOP;
20992                         app.adjType = "vis-activity";
20993                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20994                     }
20995                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20996                     app.cached = false;
20997                     app.empty = false;
20998                     foregroundActivities = true;
20999                     final TaskRecord task = r.getTask();
21000                     if (task != null && minLayer > 0) {
21001                         final int layer = task.mLayerRank;
21002                         if (layer >= 0 && minLayer > layer) {
21003                             minLayer = layer;
21004                         }
21005                     }
21006                     break;
21007                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21008                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21009                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21010                         app.adjType = "pause-activity";
21011                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21012                     }
21013                     if (procState > PROCESS_STATE_CUR_TOP) {
21014                         procState = PROCESS_STATE_CUR_TOP;
21015                         app.adjType = "pause-activity";
21016                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21017                     }
21018                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21019                     app.cached = false;
21020                     app.empty = false;
21021                     foregroundActivities = true;
21022                 } else if (r.state == ActivityState.STOPPING) {
21023                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21024                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21025                         app.adjType = "stop-activity";
21026                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21027                     }
21028                     // For the process state, we will at this point consider the
21029                     // process to be cached.  It will be cached either as an activity
21030                     // or empty depending on whether the activity is finishing.  We do
21031                     // this so that we can treat the process as cached for purposes of
21032                     // memory trimming (determing current memory level, trim command to
21033                     // send to process) since there can be an arbitrary number of stopping
21034                     // processes and they should soon all go into the cached state.
21035                     if (!r.finishing) {
21036                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21037                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21038                             app.adjType = "stop-activity";
21039                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21040                         }
21041                     }
21042                     app.cached = false;
21043                     app.empty = false;
21044                     foregroundActivities = true;
21045                 } else {
21046                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21047                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21048                         app.adjType = "cch-act";
21049                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21050                     }
21051                 }
21052             }
21053             if (adj == ProcessList.VISIBLE_APP_ADJ) {
21054                 adj += minLayer;
21055             }
21056         }
21057
21058         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21059                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21060             if (app.foregroundServices) {
21061                 // The user is aware of this app, so make it visible.
21062                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21063                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21064                 app.cached = false;
21065                 app.adjType = "fg-service";
21066                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21067                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21068             } else if (app.hasOverlayUi) {
21069                 // The process is display an overlay UI.
21070                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21071                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21072                 app.cached = false;
21073                 app.adjType = "has-overlay-ui";
21074                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21075                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21076             }
21077         }
21078
21079         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21080                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21081             if (app.forcingToImportant != null) {
21082                 // This is currently used for toasts...  they are not interactive, and
21083                 // we don't want them to cause the app to become fully foreground (and
21084                 // thus out of background check), so we yes the best background level we can.
21085                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21086                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21087                 app.cached = false;
21088                 app.adjType = "force-imp";
21089                 app.adjSource = app.forcingToImportant;
21090                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21091                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21092             }
21093         }
21094
21095         if (app == mHeavyWeightProcess) {
21096             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21097                 // We don't want to kill the current heavy-weight process.
21098                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21099                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21100                 app.cached = false;
21101                 app.adjType = "heavy";
21102                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21103             }
21104             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21105                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21106                 app.adjType = "heavy";
21107                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21108             }
21109         }
21110
21111         if (app == mHomeProcess) {
21112             if (adj > ProcessList.HOME_APP_ADJ) {
21113                 // This process is hosting what we currently consider to be the
21114                 // home app, so we don't want to let it go into the background.
21115                 adj = ProcessList.HOME_APP_ADJ;
21116                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21117                 app.cached = false;
21118                 app.adjType = "home";
21119                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21120             }
21121             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21122                 procState = ActivityManager.PROCESS_STATE_HOME;
21123                 app.adjType = "home";
21124                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21125             }
21126         }
21127
21128         if (app == mPreviousProcess && app.activities.size() > 0) {
21129             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21130                 // This was the previous process that showed UI to the user.
21131                 // We want to try to keep it around more aggressively, to give
21132                 // a good experience around switching between two apps.
21133                 adj = ProcessList.PREVIOUS_APP_ADJ;
21134                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21135                 app.cached = false;
21136                 app.adjType = "previous";
21137                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21138             }
21139             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21140                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21141                 app.adjType = "previous";
21142                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21143             }
21144         }
21145
21146         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21147                 + " reason=" + app.adjType);
21148
21149         // By default, we use the computed adjustment.  It may be changed if
21150         // there are applications dependent on our services or providers, but
21151         // this gives us a baseline and makes sure we don't get into an
21152         // infinite recursion.
21153         app.adjSeq = mAdjSeq;
21154         app.curRawAdj = adj;
21155         app.hasStartedServices = false;
21156
21157         if (mBackupTarget != null && app == mBackupTarget.app) {
21158             // If possible we want to avoid killing apps while they're being backed up
21159             if (adj > ProcessList.BACKUP_APP_ADJ) {
21160                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21161                 adj = ProcessList.BACKUP_APP_ADJ;
21162                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21163                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21164                 }
21165                 app.adjType = "backup";
21166                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21167                 app.cached = false;
21168             }
21169             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21170                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21171                 app.adjType = "backup";
21172                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21173             }
21174         }
21175
21176         boolean mayBeTop = false;
21177         String mayBeTopType = null;
21178         Object mayBeTopSource = null;
21179         Object mayBeTopTarget = null;
21180
21181         for (int is = app.services.size()-1;
21182                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21183                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21184                         || procState > ActivityManager.PROCESS_STATE_TOP);
21185                 is--) {
21186             ServiceRecord s = app.services.valueAt(is);
21187             if (s.startRequested) {
21188                 app.hasStartedServices = true;
21189                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21190                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21191                     app.adjType = "started-services";
21192                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21193                 }
21194                 if (app.hasShownUi && app != mHomeProcess) {
21195                     // If this process has shown some UI, let it immediately
21196                     // go to the LRU list because it may be pretty heavy with
21197                     // UI stuff.  We'll tag it with a label just to help
21198                     // debug and understand what is going on.
21199                     if (adj > ProcessList.SERVICE_ADJ) {
21200                         app.adjType = "cch-started-ui-services";
21201                     }
21202                 } else {
21203                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21204                         // This service has seen some activity within
21205                         // recent memory, so we will keep its process ahead
21206                         // of the background processes.
21207                         if (adj > ProcessList.SERVICE_ADJ) {
21208                             adj = ProcessList.SERVICE_ADJ;
21209                             app.adjType = "started-services";
21210                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21211                             app.cached = false;
21212                         }
21213                     }
21214                     // If we have let the service slide into the background
21215                     // state, still have some text describing what it is doing
21216                     // even though the service no longer has an impact.
21217                     if (adj > ProcessList.SERVICE_ADJ) {
21218                         app.adjType = "cch-started-services";
21219                     }
21220                 }
21221             }
21222
21223             for (int conni = s.connections.size()-1;
21224                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21225                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21226                             || procState > ActivityManager.PROCESS_STATE_TOP);
21227                     conni--) {
21228                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21229                 for (int i = 0;
21230                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21231                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21232                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21233                         i++) {
21234                     // XXX should compute this based on the max of
21235                     // all connected clients.
21236                     ConnectionRecord cr = clist.get(i);
21237                     if (cr.binding.client == app) {
21238                         // Binding to ourself is not interesting.
21239                         continue;
21240                     }
21241
21242                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21243                         ProcessRecord client = cr.binding.client;
21244                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21245                                 TOP_APP, doingAll, now);
21246                         int clientProcState = client.curProcState;
21247                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21248                             // If the other app is cached for any reason, for purposes here
21249                             // we are going to consider it empty.  The specific cached state
21250                             // doesn't propagate except under certain conditions.
21251                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21252                         }
21253                         String adjType = null;
21254                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21255                             // Not doing bind OOM management, so treat
21256                             // this guy more like a started service.
21257                             if (app.hasShownUi && app != mHomeProcess) {
21258                                 // If this process has shown some UI, let it immediately
21259                                 // go to the LRU list because it may be pretty heavy with
21260                                 // UI stuff.  We'll tag it with a label just to help
21261                                 // debug and understand what is going on.
21262                                 if (adj > clientAdj) {
21263                                     adjType = "cch-bound-ui-services";
21264                                 }
21265                                 app.cached = false;
21266                                 clientAdj = adj;
21267                                 clientProcState = procState;
21268                             } else {
21269                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21270                                     // This service has not seen activity within
21271                                     // recent memory, so allow it to drop to the
21272                                     // LRU list if there is no other reason to keep
21273                                     // it around.  We'll also tag it with a label just
21274                                     // to help debug and undertand what is going on.
21275                                     if (adj > clientAdj) {
21276                                         adjType = "cch-bound-services";
21277                                     }
21278                                     clientAdj = adj;
21279                                 }
21280                             }
21281                         }
21282                         if (adj > clientAdj) {
21283                             // If this process has recently shown UI, and
21284                             // the process that is binding to it is less
21285                             // important than being visible, then we don't
21286                             // care about the binding as much as we care
21287                             // about letting this process get into the LRU
21288                             // list to be killed and restarted if needed for
21289                             // memory.
21290                             if (app.hasShownUi && app != mHomeProcess
21291                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21292                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21293                                     adjType = "cch-bound-ui-services";
21294                                 }
21295                             } else {
21296                                 int newAdj;
21297                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21298                                         |Context.BIND_IMPORTANT)) != 0) {
21299                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21300                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21301                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21302                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21303                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21304                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21305                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21306                                     newAdj = clientAdj;
21307                                 } else {
21308                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21309                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21310                                     } else {
21311                                         newAdj = adj;
21312                                     }
21313                                 }
21314                                 if (!client.cached) {
21315                                     app.cached = false;
21316                                 }
21317                                 if (adj >  newAdj) {
21318                                     adj = newAdj;
21319                                     adjType = "service";
21320                                 }
21321                             }
21322                         }
21323                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21324                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21325                             // This will treat important bound services identically to
21326                             // the top app, which may behave differently than generic
21327                             // foreground work.
21328                             if (client.curSchedGroup > schedGroup) {
21329                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21330                                     schedGroup = client.curSchedGroup;
21331                                 } else {
21332                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21333                                 }
21334                             }
21335                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21336                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21337                                     // Special handling of clients who are in the top state.
21338                                     // We *may* want to consider this process to be in the
21339                                     // top state as well, but only if there is not another
21340                                     // reason for it to be running.  Being on the top is a
21341                                     // special state, meaning you are specifically running
21342                                     // for the current top app.  If the process is already
21343                                     // running in the background for some other reason, it
21344                                     // is more important to continue considering it to be
21345                                     // in the background state.
21346                                     mayBeTop = true;
21347                                     mayBeTopType = "service";
21348                                     mayBeTopSource = cr.binding.client;
21349                                     mayBeTopTarget = s.name;
21350                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21351                                 } else {
21352                                     // Special handling for above-top states (persistent
21353                                     // processes).  These should not bring the current process
21354                                     // into the top state, since they are not on top.  Instead
21355                                     // give them the best state after that.
21356                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21357                                         clientProcState =
21358                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21359                                     } else if (mWakefulness
21360                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21361                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21362                                                     != 0) {
21363                                         clientProcState =
21364                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21365                                     } else {
21366                                         clientProcState =
21367                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21368                                     }
21369                                 }
21370                             }
21371                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21372                             if (clientProcState <
21373                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21374                                 clientProcState =
21375                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21376                             }
21377                         } else {
21378                             if (clientProcState <
21379                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21380                                 clientProcState =
21381                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21382                             }
21383                         }
21384                         if (procState > clientProcState) {
21385                             procState = clientProcState;
21386                             if (adjType == null) {
21387                                 adjType = "service";
21388                             }
21389                         }
21390                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21391                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21392                             app.pendingUiClean = true;
21393                         }
21394                         if (adjType != null) {
21395                             app.adjType = adjType;
21396                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21397                                     .REASON_SERVICE_IN_USE;
21398                             app.adjSource = cr.binding.client;
21399                             app.adjSourceProcState = clientProcState;
21400                             app.adjTarget = s.name;
21401                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21402                                     + ": " + app + ", due to " + cr.binding.client
21403                                     + " adj=" + adj + " procState=" + procState);
21404                         }
21405                     }
21406                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21407                         app.treatLikeActivity = true;
21408                     }
21409                     final ActivityRecord a = cr.activity;
21410                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21411                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21412                             (a.visible || a.state == ActivityState.RESUMED ||
21413                              a.state == ActivityState.PAUSING)) {
21414                             adj = ProcessList.FOREGROUND_APP_ADJ;
21415                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21416                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21417                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21418                                 } else {
21419                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21420                                 }
21421                             }
21422                             app.cached = false;
21423                             app.adjType = "service";
21424                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21425                                     .REASON_SERVICE_IN_USE;
21426                             app.adjSource = a;
21427                             app.adjSourceProcState = procState;
21428                             app.adjTarget = s.name;
21429                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21430                                     + app);
21431                         }
21432                     }
21433                 }
21434             }
21435         }
21436
21437         for (int provi = app.pubProviders.size()-1;
21438                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21439                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21440                         || procState > ActivityManager.PROCESS_STATE_TOP);
21441                 provi--) {
21442             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21443             for (int i = cpr.connections.size()-1;
21444                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21445                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21446                             || procState > ActivityManager.PROCESS_STATE_TOP);
21447                     i--) {
21448                 ContentProviderConnection conn = cpr.connections.get(i);
21449                 ProcessRecord client = conn.client;
21450                 if (client == app) {
21451                     // Being our own client is not interesting.
21452                     continue;
21453                 }
21454                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21455                 int clientProcState = client.curProcState;
21456                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21457                     // If the other app is cached for any reason, for purposes here
21458                     // we are going to consider it empty.
21459                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21460                 }
21461                 String adjType = null;
21462                 if (adj > clientAdj) {
21463                     if (app.hasShownUi && app != mHomeProcess
21464                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21465                         adjType = "cch-ui-provider";
21466                     } else {
21467                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21468                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21469                         adjType = "provider";
21470                     }
21471                     app.cached &= client.cached;
21472                 }
21473                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21474                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21475                         // Special handling of clients who are in the top state.
21476                         // We *may* want to consider this process to be in the
21477                         // top state as well, but only if there is not another
21478                         // reason for it to be running.  Being on the top is a
21479                         // special state, meaning you are specifically running
21480                         // for the current top app.  If the process is already
21481                         // running in the background for some other reason, it
21482                         // is more important to continue considering it to be
21483                         // in the background state.
21484                         mayBeTop = true;
21485                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21486                         mayBeTopType = adjType = "provider-top";
21487                         mayBeTopSource = client;
21488                         mayBeTopTarget = cpr.name;
21489                     } else {
21490                         // Special handling for above-top states (persistent
21491                         // processes).  These should not bring the current process
21492                         // into the top state, since they are not on top.  Instead
21493                         // give them the best state after that.
21494                         clientProcState =
21495                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21496                         if (adjType == null) {
21497                             adjType = "provider";
21498                         }
21499                     }
21500                 }
21501                 if (procState > clientProcState) {
21502                     procState = clientProcState;
21503                 }
21504                 if (client.curSchedGroup > schedGroup) {
21505                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21506                 }
21507                 if (adjType != null) {
21508                     app.adjType = adjType;
21509                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21510                             .REASON_PROVIDER_IN_USE;
21511                     app.adjSource = client;
21512                     app.adjSourceProcState = clientProcState;
21513                     app.adjTarget = cpr.name;
21514                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21515                             + ": " + app + ", due to " + client
21516                             + " adj=" + adj + " procState=" + procState);
21517                 }
21518             }
21519             // If the provider has external (non-framework) process
21520             // dependencies, ensure that its adjustment is at least
21521             // FOREGROUND_APP_ADJ.
21522             if (cpr.hasExternalProcessHandles()) {
21523                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21524                     adj = ProcessList.FOREGROUND_APP_ADJ;
21525                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21526                     app.cached = false;
21527                     app.adjType = "ext-provider";
21528                     app.adjTarget = cpr.name;
21529                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21530                 }
21531                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21532                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21533                 }
21534             }
21535         }
21536
21537         if (app.lastProviderTime > 0 &&
21538                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21539             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21540                 adj = ProcessList.PREVIOUS_APP_ADJ;
21541                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21542                 app.cached = false;
21543                 app.adjType = "recent-provider";
21544                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21545             }
21546             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21547                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21548                 app.adjType = "recent-provider";
21549                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21550             }
21551         }
21552
21553         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21554             // A client of one of our services or providers is in the top state.  We
21555             // *may* want to be in the top state, but not if we are already running in
21556             // the background for some other reason.  For the decision here, we are going
21557             // to pick out a few specific states that we want to remain in when a client
21558             // is top (states that tend to be longer-term) and otherwise allow it to go
21559             // to the top state.
21560             switch (procState) {
21561                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21562                     // Something else is keeping it at this level, just leave it.
21563                     break;
21564                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21565                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21566                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21567                 case ActivityManager.PROCESS_STATE_SERVICE:
21568                     // These all are longer-term states, so pull them up to the top
21569                     // of the background states, but not all the way to the top state.
21570                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21571                     app.adjType = mayBeTopType;
21572                     app.adjSource = mayBeTopSource;
21573                     app.adjTarget = mayBeTopTarget;
21574                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21575                             + ": " + app + ", due to " + mayBeTopSource
21576                             + " adj=" + adj + " procState=" + procState);
21577                     break;
21578                 default:
21579                     // Otherwise, top is a better choice, so take it.
21580                     procState = ActivityManager.PROCESS_STATE_TOP;
21581                     app.adjType = mayBeTopType;
21582                     app.adjSource = mayBeTopSource;
21583                     app.adjTarget = mayBeTopTarget;
21584                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21585                             + ": " + app + ", due to " + mayBeTopSource
21586                             + " adj=" + adj + " procState=" + procState);
21587                     break;
21588             }
21589         }
21590
21591         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21592             if (app.hasClientActivities) {
21593                 // This is a cached process, but with client activities.  Mark it so.
21594                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21595                 app.adjType = "cch-client-act";
21596             } else if (app.treatLikeActivity) {
21597                 // This is a cached process, but somebody wants us to treat it like it has
21598                 // an activity, okay!
21599                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21600                 app.adjType = "cch-as-act";
21601             }
21602         }
21603
21604         if (adj == ProcessList.SERVICE_ADJ) {
21605             if (doingAll) {
21606                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21607                 mNewNumServiceProcs++;
21608                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21609                 if (!app.serviceb) {
21610                     // This service isn't far enough down on the LRU list to
21611                     // normally be a B service, but if we are low on RAM and it
21612                     // is large we want to force it down since we would prefer to
21613                     // keep launcher over it.
21614                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21615                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21616                         app.serviceHighRam = true;
21617                         app.serviceb = true;
21618                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21619                     } else {
21620                         mNewNumAServiceProcs++;
21621                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21622                     }
21623                 } else {
21624                     app.serviceHighRam = false;
21625                 }
21626             }
21627             if (app.serviceb) {
21628                 adj = ProcessList.SERVICE_B_ADJ;
21629             }
21630         }
21631
21632         app.curRawAdj = adj;
21633
21634         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21635         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21636         if (adj > app.maxAdj) {
21637             adj = app.maxAdj;
21638             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21639                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21640             }
21641         }
21642
21643         // Do final modification to adj.  Everything we do between here and applying
21644         // the final setAdj must be done in this function, because we will also use
21645         // it when computing the final cached adj later.  Note that we don't need to
21646         // worry about this for max adj above, since max adj will always be used to
21647         // keep it out of the cached vaues.
21648         app.curAdj = app.modifyRawOomAdj(adj);
21649         app.curSchedGroup = schedGroup;
21650         app.curProcState = procState;
21651         app.foregroundActivities = foregroundActivities;
21652
21653         return app.curRawAdj;
21654     }
21655
21656     /**
21657      * Record new PSS sample for a process.
21658      */
21659     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21660             long now) {
21661         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21662                 swapPss * 1024);
21663         proc.lastPssTime = now;
21664         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21665         if (DEBUG_PSS) Slog.d(TAG_PSS,
21666                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21667                 + " state=" + ProcessList.makeProcStateString(procState));
21668         if (proc.initialIdlePss == 0) {
21669             proc.initialIdlePss = pss;
21670         }
21671         proc.lastPss = pss;
21672         proc.lastSwapPss = swapPss;
21673         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21674             proc.lastCachedPss = pss;
21675             proc.lastCachedSwapPss = swapPss;
21676         }
21677
21678         final SparseArray<Pair<Long, String>> watchUids
21679                 = mMemWatchProcesses.getMap().get(proc.processName);
21680         Long check = null;
21681         if (watchUids != null) {
21682             Pair<Long, String> val = watchUids.get(proc.uid);
21683             if (val == null) {
21684                 val = watchUids.get(0);
21685             }
21686             if (val != null) {
21687                 check = val.first;
21688             }
21689         }
21690         if (check != null) {
21691             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21692                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21693                 if (!isDebuggable) {
21694                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21695                         isDebuggable = true;
21696                     }
21697                 }
21698                 if (isDebuggable) {
21699                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21700                     final ProcessRecord myProc = proc;
21701                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21702                     mMemWatchDumpProcName = proc.processName;
21703                     mMemWatchDumpFile = heapdumpFile.toString();
21704                     mMemWatchDumpPid = proc.pid;
21705                     mMemWatchDumpUid = proc.uid;
21706                     BackgroundThread.getHandler().post(new Runnable() {
21707                         @Override
21708                         public void run() {
21709                             revokeUriPermission(ActivityThread.currentActivityThread()
21710                                             .getApplicationThread(),
21711                                     null, DumpHeapActivity.JAVA_URI,
21712                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21713                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21714                                     UserHandle.myUserId());
21715                             ParcelFileDescriptor fd = null;
21716                             try {
21717                                 heapdumpFile.delete();
21718                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21719                                         ParcelFileDescriptor.MODE_CREATE |
21720                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21721                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21722                                                 ParcelFileDescriptor.MODE_APPEND);
21723                                 IApplicationThread thread = myProc.thread;
21724                                 if (thread != null) {
21725                                     try {
21726                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21727                                                 "Requesting dump heap from "
21728                                                 + myProc + " to " + heapdumpFile);
21729                                         thread.dumpHeap(/* managed= */ true,
21730                                                 /* mallocInfo= */ false, /* runGc= */ false,
21731                                                 heapdumpFile.toString(), fd);
21732                                     } catch (RemoteException e) {
21733                                     }
21734                                 }
21735                             } catch (FileNotFoundException e) {
21736                                 e.printStackTrace();
21737                             } finally {
21738                                 if (fd != null) {
21739                                     try {
21740                                         fd.close();
21741                                     } catch (IOException e) {
21742                                     }
21743                                 }
21744                             }
21745                         }
21746                     });
21747                 } else {
21748                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21749                             + ", but debugging not enabled");
21750                 }
21751             }
21752         }
21753     }
21754
21755     /**
21756      * Schedule PSS collection of a process.
21757      */
21758     void requestPssLocked(ProcessRecord proc, int procState) {
21759         if (mPendingPssProcesses.contains(proc)) {
21760             return;
21761         }
21762         if (mPendingPssProcesses.size() == 0) {
21763             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21764         }
21765         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21766         proc.pssProcState = procState;
21767         mPendingPssProcesses.add(proc);
21768     }
21769
21770     /**
21771      * Schedule PSS collection of all processes.
21772      */
21773     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21774         if (!always) {
21775             if (now < (mLastFullPssTime +
21776                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21777                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21778                 return;
21779             }
21780         }
21781         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21782         mLastFullPssTime = now;
21783         mFullPssPending = true;
21784         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21785         mPendingPssProcesses.clear();
21786         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21787             ProcessRecord app = mLruProcesses.get(i);
21788             if (app.thread == null
21789                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21790                 continue;
21791             }
21792             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21793                 app.pssProcState = app.setProcState;
21794                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21795                         mTestPssMode, isSleepingLocked(), now);
21796                 mPendingPssProcesses.add(app);
21797             }
21798         }
21799         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21800     }
21801
21802     public void setTestPssMode(boolean enabled) {
21803         synchronized (this) {
21804             mTestPssMode = enabled;
21805             if (enabled) {
21806                 // Whenever we enable the mode, we want to take a snapshot all of current
21807                 // process mem use.
21808                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21809             }
21810         }
21811     }
21812
21813     /**
21814      * Ask a given process to GC right now.
21815      */
21816     final void performAppGcLocked(ProcessRecord app) {
21817         try {
21818             app.lastRequestedGc = SystemClock.uptimeMillis();
21819             if (app.thread != null) {
21820                 if (app.reportLowMemory) {
21821                     app.reportLowMemory = false;
21822                     app.thread.scheduleLowMemory();
21823                 } else {
21824                     app.thread.processInBackground();
21825                 }
21826             }
21827         } catch (Exception e) {
21828             // whatever.
21829         }
21830     }
21831
21832     /**
21833      * Returns true if things are idle enough to perform GCs.
21834      */
21835     private final boolean canGcNowLocked() {
21836         boolean processingBroadcasts = false;
21837         for (BroadcastQueue q : mBroadcastQueues) {
21838             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21839                 processingBroadcasts = true;
21840             }
21841         }
21842         return !processingBroadcasts
21843                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21844     }
21845
21846     /**
21847      * Perform GCs on all processes that are waiting for it, but only
21848      * if things are idle.
21849      */
21850     final void performAppGcsLocked() {
21851         final int N = mProcessesToGc.size();
21852         if (N <= 0) {
21853             return;
21854         }
21855         if (canGcNowLocked()) {
21856             while (mProcessesToGc.size() > 0) {
21857                 ProcessRecord proc = mProcessesToGc.remove(0);
21858                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21859                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21860                             <= SystemClock.uptimeMillis()) {
21861                         // To avoid spamming the system, we will GC processes one
21862                         // at a time, waiting a few seconds between each.
21863                         performAppGcLocked(proc);
21864                         scheduleAppGcsLocked();
21865                         return;
21866                     } else {
21867                         // It hasn't been long enough since we last GCed this
21868                         // process...  put it in the list to wait for its time.
21869                         addProcessToGcListLocked(proc);
21870                         break;
21871                     }
21872                 }
21873             }
21874
21875             scheduleAppGcsLocked();
21876         }
21877     }
21878
21879     /**
21880      * If all looks good, perform GCs on all processes waiting for them.
21881      */
21882     final void performAppGcsIfAppropriateLocked() {
21883         if (canGcNowLocked()) {
21884             performAppGcsLocked();
21885             return;
21886         }
21887         // Still not idle, wait some more.
21888         scheduleAppGcsLocked();
21889     }
21890
21891     /**
21892      * Schedule the execution of all pending app GCs.
21893      */
21894     final void scheduleAppGcsLocked() {
21895         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21896
21897         if (mProcessesToGc.size() > 0) {
21898             // Schedule a GC for the time to the next process.
21899             ProcessRecord proc = mProcessesToGc.get(0);
21900             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21901
21902             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21903             long now = SystemClock.uptimeMillis();
21904             if (when < (now+mConstants.GC_TIMEOUT)) {
21905                 when = now + mConstants.GC_TIMEOUT;
21906             }
21907             mHandler.sendMessageAtTime(msg, when);
21908         }
21909     }
21910
21911     /**
21912      * Add a process to the array of processes waiting to be GCed.  Keeps the
21913      * list in sorted order by the last GC time.  The process can't already be
21914      * on the list.
21915      */
21916     final void addProcessToGcListLocked(ProcessRecord proc) {
21917         boolean added = false;
21918         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21919             if (mProcessesToGc.get(i).lastRequestedGc <
21920                     proc.lastRequestedGc) {
21921                 added = true;
21922                 mProcessesToGc.add(i+1, proc);
21923                 break;
21924             }
21925         }
21926         if (!added) {
21927             mProcessesToGc.add(0, proc);
21928         }
21929     }
21930
21931     /**
21932      * Set up to ask a process to GC itself.  This will either do it
21933      * immediately, or put it on the list of processes to gc the next
21934      * time things are idle.
21935      */
21936     final void scheduleAppGcLocked(ProcessRecord app) {
21937         long now = SystemClock.uptimeMillis();
21938         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21939             return;
21940         }
21941         if (!mProcessesToGc.contains(app)) {
21942             addProcessToGcListLocked(app);
21943             scheduleAppGcsLocked();
21944         }
21945     }
21946
21947     final void checkExcessivePowerUsageLocked() {
21948         updateCpuStatsNow();
21949
21950         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21951         boolean doCpuKills = true;
21952         if (mLastPowerCheckUptime == 0) {
21953             doCpuKills = false;
21954         }
21955         final long curUptime = SystemClock.uptimeMillis();
21956         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21957         mLastPowerCheckUptime = curUptime;
21958         int i = mLruProcesses.size();
21959         while (i > 0) {
21960             i--;
21961             ProcessRecord app = mLruProcesses.get(i);
21962             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21963                 if (app.lastCpuTime <= 0) {
21964                     continue;
21965                 }
21966                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21967                 if (DEBUG_POWER) {
21968                     StringBuilder sb = new StringBuilder(128);
21969                     sb.append("CPU for ");
21970                     app.toShortString(sb);
21971                     sb.append(": over ");
21972                     TimeUtils.formatDuration(uptimeSince, sb);
21973                     sb.append(" used ");
21974                     TimeUtils.formatDuration(cputimeUsed, sb);
21975                     sb.append(" (");
21976                     sb.append((cputimeUsed*100)/uptimeSince);
21977                     sb.append("%)");
21978                     Slog.i(TAG_POWER, sb.toString());
21979                 }
21980                 // If the process has used too much CPU over the last duration, the
21981                 // user probably doesn't want this, so kill!
21982                 if (doCpuKills && uptimeSince > 0) {
21983                     // What is the limit for this process?
21984                     int cpuLimit;
21985                     long checkDur = curUptime - app.whenUnimportant;
21986                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21987                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21988                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21989                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21990                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21991                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21992                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21993                     } else {
21994                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21995                     }
21996                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21997                         synchronized (stats) {
21998                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21999                                     uptimeSince, cputimeUsed);
22000                         }
22001                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22002                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22003                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22004                     }
22005                 }
22006                 app.lastCpuTime = app.curCpuTime;
22007             }
22008         }
22009     }
22010
22011     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22012             long nowElapsed) {
22013         boolean success = true;
22014
22015         if (app.curRawAdj != app.setRawAdj) {
22016             app.setRawAdj = app.curRawAdj;
22017         }
22018
22019         int changes = 0;
22020
22021         if (app.curAdj != app.setAdj) {
22022             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22023             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22024                 String msg = "Set " + app.pid + " " + app.processName + " adj "
22025                         + app.curAdj + ": " + app.adjType;
22026                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22027             }
22028             app.setAdj = app.curAdj;
22029             app.verifiedAdj = ProcessList.INVALID_ADJ;
22030         }
22031
22032         if (app.setSchedGroup != app.curSchedGroup) {
22033             int oldSchedGroup = app.setSchedGroup;
22034             app.setSchedGroup = app.curSchedGroup;
22035             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22036                 String msg = "Setting sched group of " + app.processName
22037                         + " to " + app.curSchedGroup;
22038                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22039             }
22040             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22041                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22042                 app.kill(app.waitingToKill, true);
22043                 success = false;
22044             } else {
22045                 int processGroup;
22046                 switch (app.curSchedGroup) {
22047                     case ProcessList.SCHED_GROUP_BACKGROUND:
22048                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22049                         break;
22050                     case ProcessList.SCHED_GROUP_TOP_APP:
22051                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22052                         processGroup = THREAD_GROUP_TOP_APP;
22053                         break;
22054                     default:
22055                         processGroup = THREAD_GROUP_DEFAULT;
22056                         break;
22057                 }
22058                 long oldId = Binder.clearCallingIdentity();
22059                 try {
22060                     setProcessGroup(app.pid, processGroup);
22061                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22062                         // do nothing if we already switched to RT
22063                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22064                             mVrController.onTopProcChangedLocked(app);
22065                             if (mUseFifoUiScheduling) {
22066                                 // Switch UI pipeline for app to SCHED_FIFO
22067                                 app.savedPriority = Process.getThreadPriority(app.pid);
22068                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22069                                 if (app.renderThreadTid != 0) {
22070                                     scheduleAsFifoPriority(app.renderThreadTid,
22071                                         /* suppressLogs */true);
22072                                     if (DEBUG_OOM_ADJ) {
22073                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22074                                             app.renderThreadTid + ") to FIFO");
22075                                     }
22076                                 } else {
22077                                     if (DEBUG_OOM_ADJ) {
22078                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22079                                     }
22080                                 }
22081                             } else {
22082                                 // Boost priority for top app UI and render threads
22083                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22084                                 if (app.renderThreadTid != 0) {
22085                                     try {
22086                                         setThreadPriority(app.renderThreadTid,
22087                                                 TOP_APP_PRIORITY_BOOST);
22088                                     } catch (IllegalArgumentException e) {
22089                                         // thread died, ignore
22090                                     }
22091                                 }
22092                             }
22093                         }
22094                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22095                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22096                         mVrController.onTopProcChangedLocked(app);
22097                         if (mUseFifoUiScheduling) {
22098                             try {
22099                                 // Reset UI pipeline to SCHED_OTHER
22100                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22101                                 setThreadPriority(app.pid, app.savedPriority);
22102                                 if (app.renderThreadTid != 0) {
22103                                     setThreadScheduler(app.renderThreadTid,
22104                                         SCHED_OTHER, 0);
22105                                     setThreadPriority(app.renderThreadTid, -4);
22106                                 }
22107                             } catch (IllegalArgumentException e) {
22108                                 Slog.w(TAG,
22109                                         "Failed to set scheduling policy, thread does not exist:\n"
22110                                                 + e);
22111                             } catch (SecurityException e) {
22112                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22113                             }
22114                         } else {
22115                             // Reset priority for top app UI and render threads
22116                             setThreadPriority(app.pid, 0);
22117                             if (app.renderThreadTid != 0) {
22118                                 setThreadPriority(app.renderThreadTid, 0);
22119                             }
22120                         }
22121                     }
22122                 } catch (Exception e) {
22123                     if (false) {
22124                         Slog.w(TAG, "Failed setting process group of " + app.pid
22125                                 + " to " + app.curSchedGroup);
22126                         Slog.w(TAG, "at location", e);
22127                     }
22128                 } finally {
22129                     Binder.restoreCallingIdentity(oldId);
22130                 }
22131             }
22132         }
22133         if (app.repForegroundActivities != app.foregroundActivities) {
22134             app.repForegroundActivities = app.foregroundActivities;
22135             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22136         }
22137         if (app.repProcState != app.curProcState) {
22138             app.repProcState = app.curProcState;
22139             if (app.thread != null) {
22140                 try {
22141                     if (false) {
22142                         //RuntimeException h = new RuntimeException("here");
22143                         Slog.i(TAG, "Sending new process state " + app.repProcState
22144                                 + " to " + app /*, h*/);
22145                     }
22146                     app.thread.setProcessState(app.repProcState);
22147                 } catch (RemoteException e) {
22148                 }
22149             }
22150         }
22151         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22152                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22153             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22154                 // Experimental code to more aggressively collect pss while
22155                 // running test...  the problem is that this tends to collect
22156                 // the data right when a process is transitioning between process
22157                 // states, which well tend to give noisy data.
22158                 long start = SystemClock.uptimeMillis();
22159                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22160                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22161                 mPendingPssProcesses.remove(app);
22162                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22163                         + " to " + app.curProcState + ": "
22164                         + (SystemClock.uptimeMillis()-start) + "ms");
22165             }
22166             app.lastStateTime = now;
22167             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22168                     mTestPssMode, isSleepingLocked(), now);
22169             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22170                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22171                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22172                     + (app.nextPssTime-now) + ": " + app);
22173         } else {
22174             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22175                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22176                     mTestPssMode)))) {
22177                 requestPssLocked(app, app.setProcState);
22178                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22179                         mTestPssMode, isSleepingLocked(), now);
22180             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22181                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22182         }
22183         if (app.setProcState != app.curProcState) {
22184             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22185                 String msg = "Proc state change of " + app.processName
22186                         + " to " + app.curProcState;
22187                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22188             }
22189             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22190             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22191             if (setImportant && !curImportant) {
22192                 // This app is no longer something we consider important enough to allow to
22193                 // use arbitrary amounts of battery power.  Note
22194                 // its current CPU time to later know to kill it if
22195                 // it is not behaving well.
22196                 app.whenUnimportant = now;
22197                 app.lastCpuTime = 0;
22198             }
22199             // Inform UsageStats of important process state change
22200             // Must be called before updating setProcState
22201             maybeUpdateUsageStatsLocked(app, nowElapsed);
22202
22203             app.setProcState = app.curProcState;
22204             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22205                 app.notCachedSinceIdle = false;
22206             }
22207             if (!doingAll) {
22208                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22209             } else {
22210                 app.procStateChanged = true;
22211             }
22212         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22213                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22214             // For apps that sit around for a long time in the interactive state, we need
22215             // to report this at least once a day so they don't go idle.
22216             maybeUpdateUsageStatsLocked(app, nowElapsed);
22217         }
22218
22219         if (changes != 0) {
22220             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22221                     "Changes in " + app + ": " + changes);
22222             int i = mPendingProcessChanges.size()-1;
22223             ProcessChangeItem item = null;
22224             while (i >= 0) {
22225                 item = mPendingProcessChanges.get(i);
22226                 if (item.pid == app.pid) {
22227                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228                             "Re-using existing item: " + item);
22229                     break;
22230                 }
22231                 i--;
22232             }
22233             if (i < 0) {
22234                 // No existing item in pending changes; need a new one.
22235                 final int NA = mAvailProcessChanges.size();
22236                 if (NA > 0) {
22237                     item = mAvailProcessChanges.remove(NA-1);
22238                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22239                             "Retrieving available item: " + item);
22240                 } else {
22241                     item = new ProcessChangeItem();
22242                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22243                             "Allocating new item: " + item);
22244                 }
22245                 item.changes = 0;
22246                 item.pid = app.pid;
22247                 item.uid = app.info.uid;
22248                 if (mPendingProcessChanges.size() == 0) {
22249                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22250                             "*** Enqueueing dispatch processes changed!");
22251                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22252                 }
22253                 mPendingProcessChanges.add(item);
22254             }
22255             item.changes |= changes;
22256             item.foregroundActivities = app.repForegroundActivities;
22257             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22258                     "Item " + Integer.toHexString(System.identityHashCode(item))
22259                     + " " + app.toShortString() + ": changes=" + item.changes
22260                     + " foreground=" + item.foregroundActivities
22261                     + " type=" + app.adjType + " source=" + app.adjSource
22262                     + " target=" + app.adjTarget);
22263         }
22264
22265         return success;
22266     }
22267
22268     private boolean isEphemeralLocked(int uid) {
22269         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22270         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22271             return false;
22272         }
22273         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22274                 packages[0]);
22275     }
22276
22277     @VisibleForTesting
22278     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22279         final UidRecord.ChangeItem pendingChange;
22280         if (uidRec == null || uidRec.pendingChange == null) {
22281             if (mPendingUidChanges.size() == 0) {
22282                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22283                         "*** Enqueueing dispatch uid changed!");
22284                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22285             }
22286             final int NA = mAvailUidChanges.size();
22287             if (NA > 0) {
22288                 pendingChange = mAvailUidChanges.remove(NA-1);
22289                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22290                         "Retrieving available item: " + pendingChange);
22291             } else {
22292                 pendingChange = new UidRecord.ChangeItem();
22293                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22294                         "Allocating new item: " + pendingChange);
22295             }
22296             if (uidRec != null) {
22297                 uidRec.pendingChange = pendingChange;
22298                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22299                     // If this uid is going away, and we haven't yet reported it is gone,
22300                     // then do so now.
22301                     change |= UidRecord.CHANGE_IDLE;
22302                 }
22303             } else if (uid < 0) {
22304                 throw new IllegalArgumentException("No UidRecord or uid");
22305             }
22306             pendingChange.uidRecord = uidRec;
22307             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22308             mPendingUidChanges.add(pendingChange);
22309         } else {
22310             pendingChange = uidRec.pendingChange;
22311             // If there is no change in idle or active state, then keep whatever was pending.
22312             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22313                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22314                         | UidRecord.CHANGE_ACTIVE));
22315             }
22316             // If there is no change in cached or uncached state, then keep whatever was pending.
22317             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22318                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22319                         | UidRecord.CHANGE_UNCACHED));
22320             }
22321             // If this is a report of the UID being gone, then we shouldn't keep any previous
22322             // report of it being active or cached.  (That is, a gone uid is never active,
22323             // and never cached.)
22324             if ((change & UidRecord.CHANGE_GONE) != 0) {
22325                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22326                 if (!uidRec.idle) {
22327                     // If this uid is going away, and we haven't yet reported it is gone,
22328                     // then do so now.
22329                     change |= UidRecord.CHANGE_IDLE;
22330                 }
22331             }
22332         }
22333         pendingChange.change = change;
22334         pendingChange.processState = uidRec != null
22335                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22336         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22337         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22338         if (uidRec != null) {
22339             uidRec.lastReportedChange = change;
22340             uidRec.updateLastDispatchedProcStateSeq(change);
22341         }
22342
22343         // Directly update the power manager, since we sit on top of it and it is critical
22344         // it be kept in sync (so wake locks will be held as soon as appropriate).
22345         if (mLocalPowerManager != null) {
22346             // TO DO: dispatch cached/uncached changes here, so we don't need to report
22347             // all proc state changes.
22348             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22349                 mLocalPowerManager.uidActive(pendingChange.uid);
22350             }
22351             if ((change & UidRecord.CHANGE_IDLE) != 0) {
22352                 mLocalPowerManager.uidIdle(pendingChange.uid);
22353             }
22354             if ((change & UidRecord.CHANGE_GONE) != 0) {
22355                 mLocalPowerManager.uidGone(pendingChange.uid);
22356             } else {
22357                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22358                         pendingChange.processState);
22359             }
22360         }
22361     }
22362
22363     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22364             String authority) {
22365         if (app == null) return;
22366         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22367             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22368             if (userState == null) return;
22369             final long now = SystemClock.elapsedRealtime();
22370             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22371             if (lastReported == null || lastReported < now - 60 * 1000L) {
22372                 if (mSystemReady) {
22373                     // Cannot touch the user stats if not system ready
22374                     mUsageStatsService.reportContentProviderUsage(
22375                             authority, providerPkgName, app.userId);
22376                 }
22377                 userState.mProviderLastReportedFg.put(authority, now);
22378             }
22379         }
22380     }
22381
22382     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22383         if (DEBUG_USAGE_STATS) {
22384             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22385                     + "] state changes: old = " + app.setProcState + ", new = "
22386                     + app.curProcState);
22387         }
22388         if (mUsageStatsService == null) {
22389             return;
22390         }
22391         boolean isInteraction;
22392         // To avoid some abuse patterns, we are going to be careful about what we consider
22393         // to be an app interaction.  Being the top activity doesn't count while the display
22394         // is sleeping, nor do short foreground services.
22395         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22396             isInteraction = true;
22397             app.fgInteractionTime = 0;
22398         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22399             if (app.fgInteractionTime == 0) {
22400                 app.fgInteractionTime = nowElapsed;
22401                 isInteraction = false;
22402             } else {
22403                 isInteraction = nowElapsed > app.fgInteractionTime
22404                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22405             }
22406         } else {
22407             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22408             app.fgInteractionTime = 0;
22409         }
22410         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22411                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22412             app.interactionEventTime = nowElapsed;
22413             String[] packages = app.getPackageList();
22414             if (packages != null) {
22415                 for (int i = 0; i < packages.length; i++) {
22416                     mUsageStatsService.reportEvent(packages[i], app.userId,
22417                             UsageEvents.Event.SYSTEM_INTERACTION);
22418                 }
22419             }
22420         }
22421         app.reportedInteraction = isInteraction;
22422         if (!isInteraction) {
22423             app.interactionEventTime = 0;
22424         }
22425     }
22426
22427     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22428         if (proc.thread != null) {
22429             if (proc.baseProcessTracker != null) {
22430                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22431             }
22432         }
22433     }
22434
22435     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22436             ProcessRecord TOP_APP, boolean doingAll, long now) {
22437         if (app.thread == null) {
22438             return false;
22439         }
22440
22441         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22442
22443         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22444     }
22445
22446     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22447             boolean oomAdj) {
22448         if (isForeground != proc.foregroundServices) {
22449             proc.foregroundServices = isForeground;
22450             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22451                     proc.info.uid);
22452             if (isForeground) {
22453                 if (curProcs == null) {
22454                     curProcs = new ArrayList<ProcessRecord>();
22455                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22456                 }
22457                 if (!curProcs.contains(proc)) {
22458                     curProcs.add(proc);
22459                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22460                             proc.info.packageName, proc.info.uid);
22461                 }
22462             } else {
22463                 if (curProcs != null) {
22464                     if (curProcs.remove(proc)) {
22465                         mBatteryStatsService.noteEvent(
22466                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22467                                 proc.info.packageName, proc.info.uid);
22468                         if (curProcs.size() <= 0) {
22469                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22470                         }
22471                     }
22472                 }
22473             }
22474             if (oomAdj) {
22475                 updateOomAdjLocked();
22476             }
22477         }
22478     }
22479
22480     private final ActivityRecord resumedAppLocked() {
22481         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22482         String pkg;
22483         int uid;
22484         if (act != null) {
22485             pkg = act.packageName;
22486             uid = act.info.applicationInfo.uid;
22487         } else {
22488             pkg = null;
22489             uid = -1;
22490         }
22491         // Has the UID or resumed package name changed?
22492         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22493                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22494             if (mCurResumedPackage != null) {
22495                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22496                         mCurResumedPackage, mCurResumedUid);
22497             }
22498             mCurResumedPackage = pkg;
22499             mCurResumedUid = uid;
22500             if (mCurResumedPackage != null) {
22501                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22502                         mCurResumedPackage, mCurResumedUid);
22503             }
22504         }
22505         return act;
22506     }
22507
22508     /**
22509      * Update OomAdj for a specific process.
22510      * @param app The process to update
22511      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22512      *                  if necessary, or skip.
22513      * @return whether updateOomAdjLocked(app) was successful.
22514      */
22515     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22516         final ActivityRecord TOP_ACT = resumedAppLocked();
22517         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22518         final boolean wasCached = app.cached;
22519
22520         mAdjSeq++;
22521
22522         // This is the desired cached adjusment we want to tell it to use.
22523         // If our app is currently cached, we know it, and that is it.  Otherwise,
22524         // we don't know it yet, and it needs to now be cached we will then
22525         // need to do a complete oom adj.
22526         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22527                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22528         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22529                 SystemClock.uptimeMillis());
22530         if (oomAdjAll
22531                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22532             // Changed to/from cached state, so apps after it in the LRU
22533             // list may also be changed.
22534             updateOomAdjLocked();
22535         }
22536         return success;
22537     }
22538
22539     final void updateOomAdjLocked() {
22540         final ActivityRecord TOP_ACT = resumedAppLocked();
22541         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22542         final long now = SystemClock.uptimeMillis();
22543         final long nowElapsed = SystemClock.elapsedRealtime();
22544         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22545         final int N = mLruProcesses.size();
22546
22547         if (false) {
22548             RuntimeException e = new RuntimeException();
22549             e.fillInStackTrace();
22550             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22551         }
22552
22553         // Reset state in all uid records.
22554         for (int i=mActiveUids.size()-1; i>=0; i--) {
22555             final UidRecord uidRec = mActiveUids.valueAt(i);
22556             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22557                     "Starting update of " + uidRec);
22558             uidRec.reset();
22559         }
22560
22561         mStackSupervisor.rankTaskLayersIfNeeded();
22562
22563         mAdjSeq++;
22564         mNewNumServiceProcs = 0;
22565         mNewNumAServiceProcs = 0;
22566
22567         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22568         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22569
22570         // Let's determine how many processes we have running vs.
22571         // how many slots we have for background processes; we may want
22572         // to put multiple processes in a slot of there are enough of
22573         // them.
22574         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22575                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22576         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22577         if (numEmptyProcs > cachedProcessLimit) {
22578             // If there are more empty processes than our limit on cached
22579             // processes, then use the cached process limit for the factor.
22580             // This ensures that the really old empty processes get pushed
22581             // down to the bottom, so if we are running low on memory we will
22582             // have a better chance at keeping around more cached processes
22583             // instead of a gazillion empty processes.
22584             numEmptyProcs = cachedProcessLimit;
22585         }
22586         int emptyFactor = numEmptyProcs/numSlots;
22587         if (emptyFactor < 1) emptyFactor = 1;
22588         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22589         if (cachedFactor < 1) cachedFactor = 1;
22590         int stepCached = 0;
22591         int stepEmpty = 0;
22592         int numCached = 0;
22593         int numEmpty = 0;
22594         int numTrimming = 0;
22595
22596         mNumNonCachedProcs = 0;
22597         mNumCachedHiddenProcs = 0;
22598
22599         // First update the OOM adjustment for each of the
22600         // application processes based on their current state.
22601         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22602         int nextCachedAdj = curCachedAdj+1;
22603         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22604         int nextEmptyAdj = curEmptyAdj+2;
22605         for (int i=N-1; i>=0; i--) {
22606             ProcessRecord app = mLruProcesses.get(i);
22607             if (!app.killedByAm && app.thread != null) {
22608                 app.procStateChanged = false;
22609                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22610
22611                 // If we haven't yet assigned the final cached adj
22612                 // to the process, do that now.
22613                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22614                     switch (app.curProcState) {
22615                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22616                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22617                             // This process is a cached process holding activities...
22618                             // assign it the next cached value for that type, and then
22619                             // step that cached level.
22620                             app.curRawAdj = curCachedAdj;
22621                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22622                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22623                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22624                                     + ")");
22625                             if (curCachedAdj != nextCachedAdj) {
22626                                 stepCached++;
22627                                 if (stepCached >= cachedFactor) {
22628                                     stepCached = 0;
22629                                     curCachedAdj = nextCachedAdj;
22630                                     nextCachedAdj += 2;
22631                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22632                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22633                                     }
22634                                 }
22635                             }
22636                             break;
22637                         default:
22638                             // For everything else, assign next empty cached process
22639                             // level and bump that up.  Note that this means that
22640                             // long-running services that have dropped down to the
22641                             // cached level will be treated as empty (since their process
22642                             // state is still as a service), which is what we want.
22643                             app.curRawAdj = curEmptyAdj;
22644                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22645                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22646                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22647                                     + ")");
22648                             if (curEmptyAdj != nextEmptyAdj) {
22649                                 stepEmpty++;
22650                                 if (stepEmpty >= emptyFactor) {
22651                                     stepEmpty = 0;
22652                                     curEmptyAdj = nextEmptyAdj;
22653                                     nextEmptyAdj += 2;
22654                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22655                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22656                                     }
22657                                 }
22658                             }
22659                             break;
22660                     }
22661                 }
22662
22663                 applyOomAdjLocked(app, true, now, nowElapsed);
22664
22665                 // Count the number of process types.
22666                 switch (app.curProcState) {
22667                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22668                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22669                         mNumCachedHiddenProcs++;
22670                         numCached++;
22671                         if (numCached > cachedProcessLimit) {
22672                             app.kill("cached #" + numCached, true);
22673                         }
22674                         break;
22675                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22676                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22677                                 && app.lastActivityTime < oldTime) {
22678                             app.kill("empty for "
22679                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22680                                     / 1000) + "s", true);
22681                         } else {
22682                             numEmpty++;
22683                             if (numEmpty > emptyProcessLimit) {
22684                                 app.kill("empty #" + numEmpty, true);
22685                             }
22686                         }
22687                         break;
22688                     default:
22689                         mNumNonCachedProcs++;
22690                         break;
22691                 }
22692
22693                 if (app.isolated && app.services.size() <= 0) {
22694                     // If this is an isolated process, and there are no
22695                     // services running in it, then the process is no longer
22696                     // needed.  We agressively kill these because we can by
22697                     // definition not re-use the same process again, and it is
22698                     // good to avoid having whatever code was running in them
22699                     // left sitting around after no longer needed.
22700                     app.kill("isolated not needed", true);
22701                 } else {
22702                     // Keeping this process, update its uid.
22703                     final UidRecord uidRec = app.uidRecord;
22704                     if (uidRec != null) {
22705                         uidRec.ephemeral = app.info.isInstantApp();
22706                         if (uidRec.curProcState > app.curProcState) {
22707                             uidRec.curProcState = app.curProcState;
22708                         }
22709                         if (app.foregroundServices) {
22710                             uidRec.foregroundServices = true;
22711                         }
22712                     }
22713                 }
22714
22715                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22716                         && !app.killedByAm) {
22717                     numTrimming++;
22718                 }
22719             }
22720         }
22721
22722         incrementProcStateSeqAndNotifyAppsLocked();
22723
22724         mNumServiceProcs = mNewNumServiceProcs;
22725
22726         // Now determine the memory trimming level of background processes.
22727         // Unfortunately we need to start at the back of the list to do this
22728         // properly.  We only do this if the number of background apps we
22729         // are managing to keep around is less than half the maximum we desire;
22730         // if we are keeping a good number around, we'll let them use whatever
22731         // memory they want.
22732         final int numCachedAndEmpty = numCached + numEmpty;
22733         int memFactor;
22734         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22735                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22736             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22737                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22738             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22739                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22740             } else {
22741                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22742             }
22743         } else {
22744             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22745         }
22746         // We always allow the memory level to go up (better).  We only allow it to go
22747         // down if we are in a state where that is allowed, *and* the total number of processes
22748         // has gone down since last time.
22749         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22750                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22751                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22752         if (memFactor > mLastMemoryLevel) {
22753             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22754                 memFactor = mLastMemoryLevel;
22755                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22756             }
22757         }
22758         if (memFactor != mLastMemoryLevel) {
22759             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22760         }
22761         mLastMemoryLevel = memFactor;
22762         mLastNumProcesses = mLruProcesses.size();
22763         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22764         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22765         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22766             if (mLowRamStartTime == 0) {
22767                 mLowRamStartTime = now;
22768             }
22769             int step = 0;
22770             int fgTrimLevel;
22771             switch (memFactor) {
22772                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22773                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22774                     break;
22775                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22776                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22777                     break;
22778                 default:
22779                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22780                     break;
22781             }
22782             int factor = numTrimming/3;
22783             int minFactor = 2;
22784             if (mHomeProcess != null) minFactor++;
22785             if (mPreviousProcess != null) minFactor++;
22786             if (factor < minFactor) factor = minFactor;
22787             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22788             for (int i=N-1; i>=0; i--) {
22789                 ProcessRecord app = mLruProcesses.get(i);
22790                 if (allChanged || app.procStateChanged) {
22791                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22792                     app.procStateChanged = false;
22793                 }
22794                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22795                         && !app.killedByAm) {
22796                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22797                         try {
22798                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22799                                     "Trimming memory of " + app.processName + " to " + curLevel);
22800                             app.thread.scheduleTrimMemory(curLevel);
22801                         } catch (RemoteException e) {
22802                         }
22803                         if (false) {
22804                             // For now we won't do this; our memory trimming seems
22805                             // to be good enough at this point that destroying
22806                             // activities causes more harm than good.
22807                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22808                                     && app != mHomeProcess && app != mPreviousProcess) {
22809                                 // Need to do this on its own message because the stack may not
22810                                 // be in a consistent state at this point.
22811                                 // For these apps we will also finish their activities
22812                                 // to help them free memory.
22813                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22814                             }
22815                         }
22816                     }
22817                     app.trimMemoryLevel = curLevel;
22818                     step++;
22819                     if (step >= factor) {
22820                         step = 0;
22821                         switch (curLevel) {
22822                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22823                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22824                                 break;
22825                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22826                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22827                                 break;
22828                         }
22829                     }
22830                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22831                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22832                             && app.thread != null) {
22833                         try {
22834                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22835                                     "Trimming memory of heavy-weight " + app.processName
22836                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22837                             app.thread.scheduleTrimMemory(
22838                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22839                         } catch (RemoteException e) {
22840                         }
22841                     }
22842                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22843                 } else {
22844                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22845                             || app.systemNoUi) && app.pendingUiClean) {
22846                         // If this application is now in the background and it
22847                         // had done UI, then give it the special trim level to
22848                         // have it free UI resources.
22849                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22850                         if (app.trimMemoryLevel < level && app.thread != null) {
22851                             try {
22852                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22853                                         "Trimming memory of bg-ui " + app.processName
22854                                         + " to " + level);
22855                                 app.thread.scheduleTrimMemory(level);
22856                             } catch (RemoteException e) {
22857                             }
22858                         }
22859                         app.pendingUiClean = false;
22860                     }
22861                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22862                         try {
22863                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22864                                     "Trimming memory of fg " + app.processName
22865                                     + " to " + fgTrimLevel);
22866                             app.thread.scheduleTrimMemory(fgTrimLevel);
22867                         } catch (RemoteException e) {
22868                         }
22869                     }
22870                     app.trimMemoryLevel = fgTrimLevel;
22871                 }
22872             }
22873         } else {
22874             if (mLowRamStartTime != 0) {
22875                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22876                 mLowRamStartTime = 0;
22877             }
22878             for (int i=N-1; i>=0; i--) {
22879                 ProcessRecord app = mLruProcesses.get(i);
22880                 if (allChanged || app.procStateChanged) {
22881                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22882                     app.procStateChanged = false;
22883                 }
22884                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22885                         || app.systemNoUi) && app.pendingUiClean) {
22886                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22887                             && app.thread != null) {
22888                         try {
22889                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22890                                     "Trimming memory of ui hidden " + app.processName
22891                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22892                             app.thread.scheduleTrimMemory(
22893                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22894                         } catch (RemoteException e) {
22895                         }
22896                     }
22897                     app.pendingUiClean = false;
22898                 }
22899                 app.trimMemoryLevel = 0;
22900             }
22901         }
22902
22903         if (mAlwaysFinishActivities) {
22904             // Need to do this on its own message because the stack may not
22905             // be in a consistent state at this point.
22906             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22907         }
22908
22909         if (allChanged) {
22910             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22911         }
22912
22913         ArrayList<UidRecord> becameIdle = null;
22914
22915         // Update from any uid changes.
22916         if (mLocalPowerManager != null) {
22917             mLocalPowerManager.startUidChanges();
22918         }
22919         for (int i=mActiveUids.size()-1; i>=0; i--) {
22920             final UidRecord uidRec = mActiveUids.valueAt(i);
22921             int uidChange = UidRecord.CHANGE_PROCSTATE;
22922             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22923                     && (uidRec.setProcState != uidRec.curProcState
22924                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
22925                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22926                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22927                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22928                         + " to " + uidRec.curWhitelist);
22929                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22930                         && !uidRec.curWhitelist) {
22931                     // UID is now in the background (and not on the temp whitelist).  Was it
22932                     // previously in the foreground (or on the temp whitelist)?
22933                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22934                             || uidRec.setWhitelist) {
22935                         uidRec.lastBackgroundTime = nowElapsed;
22936                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22937                             // Note: the background settle time is in elapsed realtime, while
22938                             // the handler time base is uptime.  All this means is that we may
22939                             // stop background uids later than we had intended, but that only
22940                             // happens because the device was sleeping so we are okay anyway.
22941                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22942                                     mConstants.BACKGROUND_SETTLE_TIME);
22943                         }
22944                     }
22945                     if (uidRec.idle && !uidRec.setIdle) {
22946                         uidChange = UidRecord.CHANGE_IDLE;
22947                         if (becameIdle == null) {
22948                             becameIdle = new ArrayList<>();
22949                         }
22950                         becameIdle.add(uidRec);
22951                     }
22952                 } else {
22953                     if (uidRec.idle) {
22954                         uidChange = UidRecord.CHANGE_ACTIVE;
22955                         EventLogTags.writeAmUidActive(uidRec.uid);
22956                         uidRec.idle = false;
22957                     }
22958                     uidRec.lastBackgroundTime = 0;
22959                 }
22960                 final boolean wasCached = uidRec.setProcState
22961                         > ActivityManager.PROCESS_STATE_RECEIVER;
22962                 final boolean isCached = uidRec.curProcState
22963                         > ActivityManager.PROCESS_STATE_RECEIVER;
22964                 if (wasCached != isCached ||
22965                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22966                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22967                 }
22968                 uidRec.setProcState = uidRec.curProcState;
22969                 uidRec.setWhitelist = uidRec.curWhitelist;
22970                 uidRec.setIdle = uidRec.idle;
22971                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22972                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22973                 if (uidRec.foregroundServices) {
22974                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22975                 }
22976             }
22977         }
22978         if (mLocalPowerManager != null) {
22979             mLocalPowerManager.finishUidChanges();
22980         }
22981
22982         if (becameIdle != null) {
22983             // If we have any new uids that became idle this time, we need to make sure
22984             // they aren't left with running services.
22985             for (int i = becameIdle.size() - 1; i >= 0; i--) {
22986                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22987             }
22988         }
22989
22990         if (mProcessStats.shouldWriteNowLocked(now)) {
22991             mHandler.post(new Runnable() {
22992                 @Override public void run() {
22993                     synchronized (ActivityManagerService.this) {
22994                         mProcessStats.writeStateAsyncLocked();
22995                     }
22996                 }
22997             });
22998         }
22999
23000         if (DEBUG_OOM_ADJ) {
23001             final long duration = SystemClock.uptimeMillis() - now;
23002             if (false) {
23003                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23004                         new RuntimeException("here").fillInStackTrace());
23005             } else {
23006                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23007             }
23008         }
23009     }
23010
23011     @Override
23012     public void makePackageIdle(String packageName, int userId) {
23013         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23014                 != PackageManager.PERMISSION_GRANTED) {
23015             String msg = "Permission Denial: makePackageIdle() from pid="
23016                     + Binder.getCallingPid()
23017                     + ", uid=" + Binder.getCallingUid()
23018                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23019             Slog.w(TAG, msg);
23020             throw new SecurityException(msg);
23021         }
23022         final int callingPid = Binder.getCallingPid();
23023         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23024                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23025         long callingId = Binder.clearCallingIdentity();
23026         synchronized(this) {
23027             try {
23028                 IPackageManager pm = AppGlobals.getPackageManager();
23029                 int pkgUid = -1;
23030                 try {
23031                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23032                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23033                 } catch (RemoteException e) {
23034                 }
23035                 if (pkgUid == -1) {
23036                     throw new IllegalArgumentException("Unknown package name " + packageName);
23037                 }
23038
23039                 if (mLocalPowerManager != null) {
23040                     mLocalPowerManager.startUidChanges();
23041                 }
23042                 final int appId = UserHandle.getAppId(pkgUid);
23043                 final int N = mActiveUids.size();
23044                 for (int i=N-1; i>=0; i--) {
23045                     final UidRecord uidRec = mActiveUids.valueAt(i);
23046                     final long bgTime = uidRec.lastBackgroundTime;
23047                     if (bgTime > 0 && !uidRec.idle) {
23048                         if (UserHandle.getAppId(uidRec.uid) == appId) {
23049                             if (userId == UserHandle.USER_ALL ||
23050                                     userId == UserHandle.getUserId(uidRec.uid)) {
23051                                 EventLogTags.writeAmUidIdle(uidRec.uid);
23052                                 uidRec.idle = true;
23053                                 uidRec.setIdle = true;
23054                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23055                                         + " from package " + packageName + " user " + userId);
23056                                 doStopUidLocked(uidRec.uid, uidRec);
23057                             }
23058                         }
23059                     }
23060                 }
23061             } finally {
23062                 if (mLocalPowerManager != null) {
23063                     mLocalPowerManager.finishUidChanges();
23064                 }
23065                 Binder.restoreCallingIdentity(callingId);
23066             }
23067         }
23068     }
23069
23070     final void idleUids() {
23071         synchronized (this) {
23072             final int N = mActiveUids.size();
23073             if (N <= 0) {
23074                 return;
23075             }
23076             final long nowElapsed = SystemClock.elapsedRealtime();
23077             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23078             long nextTime = 0;
23079             if (mLocalPowerManager != null) {
23080                 mLocalPowerManager.startUidChanges();
23081             }
23082             for (int i=N-1; i>=0; i--) {
23083                 final UidRecord uidRec = mActiveUids.valueAt(i);
23084                 final long bgTime = uidRec.lastBackgroundTime;
23085                 if (bgTime > 0 && !uidRec.idle) {
23086                     if (bgTime <= maxBgTime) {
23087                         EventLogTags.writeAmUidIdle(uidRec.uid);
23088                         uidRec.idle = true;
23089                         uidRec.setIdle = true;
23090                         doStopUidLocked(uidRec.uid, uidRec);
23091                     } else {
23092                         if (nextTime == 0 || nextTime > bgTime) {
23093                             nextTime = bgTime;
23094                         }
23095                     }
23096                 }
23097             }
23098             if (mLocalPowerManager != null) {
23099                 mLocalPowerManager.finishUidChanges();
23100             }
23101             if (nextTime > 0) {
23102                 mHandler.removeMessages(IDLE_UIDS_MSG);
23103                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23104                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23105             }
23106         }
23107     }
23108
23109     /**
23110      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23111      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23112      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23113      */
23114     @VisibleForTesting
23115     @GuardedBy("this")
23116     void incrementProcStateSeqAndNotifyAppsLocked() {
23117         if (mWaitForNetworkTimeoutMs <= 0) {
23118             return;
23119         }
23120         // Used for identifying which uids need to block for network.
23121         ArrayList<Integer> blockingUids = null;
23122         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23123             final UidRecord uidRec = mActiveUids.valueAt(i);
23124             // If the network is not restricted for uid, then nothing to do here.
23125             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23126                 continue;
23127             }
23128             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23129                 continue;
23130             }
23131             // If process state is not changed, then there's nothing to do.
23132             if (uidRec.setProcState == uidRec.curProcState) {
23133                 continue;
23134             }
23135             final int blockState = getBlockStateForUid(uidRec);
23136             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23137             // there's nothing the app needs to do in this scenario.
23138             if (blockState == NETWORK_STATE_NO_CHANGE) {
23139                 continue;
23140             }
23141             synchronized (uidRec.networkStateLock) {
23142                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23143                 if (blockState == NETWORK_STATE_BLOCK) {
23144                     if (blockingUids == null) {
23145                         blockingUids = new ArrayList<>();
23146                     }
23147                     blockingUids.add(uidRec.uid);
23148                 } else {
23149                     if (DEBUG_NETWORK) {
23150                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23151                                 + " threads for uid: " + uidRec);
23152                     }
23153                     if (uidRec.waitingForNetwork) {
23154                         uidRec.networkStateLock.notifyAll();
23155                     }
23156                 }
23157             }
23158         }
23159
23160         // There are no uids that need to block, so nothing more to do.
23161         if (blockingUids == null) {
23162             return;
23163         }
23164
23165         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23166             final ProcessRecord app = mLruProcesses.get(i);
23167             if (!blockingUids.contains(app.uid)) {
23168                 continue;
23169             }
23170             if (!app.killedByAm && app.thread != null) {
23171                 final UidRecord uidRec = mActiveUids.get(app.uid);
23172                 try {
23173                     if (DEBUG_NETWORK) {
23174                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23175                                 + uidRec);
23176                     }
23177                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23178                 } catch (RemoteException ignored) {
23179                 }
23180             }
23181         }
23182     }
23183
23184     /**
23185      * Checks if the uid is coming from background to foreground or vice versa and returns
23186      * appropriate block state based on this.
23187      *
23188      * @return blockState based on whether the uid is coming from background to foreground or
23189      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23190      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23191      *         {@link #NETWORK_STATE_NO_CHANGE}.
23192      */
23193     @VisibleForTesting
23194     int getBlockStateForUid(UidRecord uidRec) {
23195         // Denotes whether uid's process state is currently allowed network access.
23196         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23197                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23198         // Denotes whether uid's process state was previously allowed network access.
23199         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23200                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23201
23202         // When the uid is coming to foreground, AMS should inform the app thread that it should
23203         // block for the network rules to get updated before launching an activity.
23204         if (!wasAllowed && isAllowed) {
23205             return NETWORK_STATE_BLOCK;
23206         }
23207         // When the uid is going to background, AMS should inform the app thread that if an
23208         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23209         if (wasAllowed && !isAllowed) {
23210             return NETWORK_STATE_UNBLOCK;
23211         }
23212         return NETWORK_STATE_NO_CHANGE;
23213     }
23214
23215     final void runInBackgroundDisabled(int uid) {
23216         synchronized (this) {
23217             UidRecord uidRec = mActiveUids.get(uid);
23218             if (uidRec != null) {
23219                 // This uid is actually running...  should it be considered background now?
23220                 if (uidRec.idle) {
23221                     doStopUidLocked(uidRec.uid, uidRec);
23222                 }
23223             } else {
23224                 // This uid isn't actually running...  still send a report about it being "stopped".
23225                 doStopUidLocked(uid, null);
23226             }
23227         }
23228     }
23229
23230     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23231         mServices.stopInBackgroundLocked(uid);
23232         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23233     }
23234
23235     /**
23236      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23237      */
23238     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23239             long duration, String tag) {
23240         if (DEBUG_WHITELISTS) {
23241             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23242                     + targetUid + ", " + duration + ")");
23243         }
23244
23245         synchronized (mPidsSelfLocked) {
23246             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23247             if (pr == null) {
23248                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23249                         + callerPid);
23250                 return;
23251             }
23252             if (!pr.whitelistManager) {
23253                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23254                         != PackageManager.PERMISSION_GRANTED) {
23255                     if (DEBUG_WHITELISTS) {
23256                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23257                                 + ": pid " + callerPid + " is not allowed");
23258                     }
23259                     return;
23260                 }
23261             }
23262         }
23263
23264         tempWhitelistUidLocked(targetUid, duration, tag);
23265     }
23266
23267     /**
23268      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23269      */
23270     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23271         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23272         setUidTempWhitelistStateLocked(targetUid, true);
23273         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23274     }
23275
23276     void pushTempWhitelist() {
23277         final int N;
23278         final PendingTempWhitelist[] list;
23279
23280         // First copy out the pending changes...  we need to leave them in the map for now,
23281         // in case someone needs to check what is coming up while we don't have the lock held.
23282         synchronized(this) {
23283             N = mPendingTempWhitelist.size();
23284             list = new PendingTempWhitelist[N];
23285             for (int i = 0; i < N; i++) {
23286                 list[i] = mPendingTempWhitelist.valueAt(i);
23287             }
23288         }
23289
23290         // Now safely dispatch changes to device idle controller.
23291         for (int i = 0; i < N; i++) {
23292             PendingTempWhitelist ptw = list[i];
23293             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23294                     ptw.duration, true, ptw.tag);
23295         }
23296
23297         // And now we can safely remove them from the map.
23298         synchronized(this) {
23299             for (int i = 0; i < N; i++) {
23300                 PendingTempWhitelist ptw = list[i];
23301                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23302                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23303                     mPendingTempWhitelist.removeAt(index);
23304                 }
23305             }
23306         }
23307     }
23308
23309     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23310         boolean changed = false;
23311         for (int i=mActiveUids.size()-1; i>=0; i--) {
23312             final UidRecord uidRec = mActiveUids.valueAt(i);
23313             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23314                 uidRec.curWhitelist = onWhitelist;
23315                 changed = true;
23316             }
23317         }
23318         if (changed) {
23319             updateOomAdjLocked();
23320         }
23321     }
23322
23323     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23324         boolean changed = false;
23325         final UidRecord uidRec = mActiveUids.get(uid);
23326         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23327             uidRec.curWhitelist = onWhitelist;
23328             updateOomAdjLocked();
23329         }
23330     }
23331
23332     final void trimApplications() {
23333         synchronized (this) {
23334             int i;
23335
23336             // First remove any unused application processes whose package
23337             // has been removed.
23338             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23339                 final ProcessRecord app = mRemovedProcesses.get(i);
23340                 if (app.activities.size() == 0
23341                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23342                     Slog.i(
23343                         TAG, "Exiting empty application process "
23344                         + app.toShortString() + " ("
23345                         + (app.thread != null ? app.thread.asBinder() : null)
23346                         + ")\n");
23347                     if (app.pid > 0 && app.pid != MY_PID) {
23348                         app.kill("empty", false);
23349                     } else {
23350                         try {
23351                             app.thread.scheduleExit();
23352                         } catch (Exception e) {
23353                             // Ignore exceptions.
23354                         }
23355                     }
23356                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23357                     mRemovedProcesses.remove(i);
23358
23359                     if (app.persistent) {
23360                         addAppLocked(app.info, null, false, null /* ABI override */);
23361                     }
23362                 }
23363             }
23364
23365             // Now update the oom adj for all processes.
23366             updateOomAdjLocked();
23367         }
23368     }
23369
23370     /** This method sends the specified signal to each of the persistent apps */
23371     public void signalPersistentProcesses(int sig) throws RemoteException {
23372         if (sig != SIGNAL_USR1) {
23373             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23374         }
23375
23376         synchronized (this) {
23377             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23378                     != PackageManager.PERMISSION_GRANTED) {
23379                 throw new SecurityException("Requires permission "
23380                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23381             }
23382
23383             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23384                 ProcessRecord r = mLruProcesses.get(i);
23385                 if (r.thread != null && r.persistent) {
23386                     sendSignal(r.pid, sig);
23387                 }
23388             }
23389         }
23390     }
23391
23392     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23393         if (proc == null || proc == mProfileProc) {
23394             proc = mProfileProc;
23395             profileType = mProfileType;
23396             clearProfilerLocked();
23397         }
23398         if (proc == null) {
23399             return;
23400         }
23401         try {
23402             proc.thread.profilerControl(false, null, profileType);
23403         } catch (RemoteException e) {
23404             throw new IllegalStateException("Process disappeared");
23405         }
23406     }
23407
23408     private void clearProfilerLocked() {
23409         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23410             try {
23411                 mProfilerInfo.profileFd.close();
23412             } catch (IOException e) {
23413             }
23414         }
23415         mProfileApp = null;
23416         mProfileProc = null;
23417         mProfilerInfo = null;
23418     }
23419
23420     public boolean profileControl(String process, int userId, boolean start,
23421             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23422
23423         try {
23424             synchronized (this) {
23425                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23426                 // its own permission.
23427                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23428                         != PackageManager.PERMISSION_GRANTED) {
23429                     throw new SecurityException("Requires permission "
23430                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23431                 }
23432
23433                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23434                     throw new IllegalArgumentException("null profile info or fd");
23435                 }
23436
23437                 ProcessRecord proc = null;
23438                 if (process != null) {
23439                     proc = findProcessLocked(process, userId, "profileControl");
23440                 }
23441
23442                 if (start && (proc == null || proc.thread == null)) {
23443                     throw new IllegalArgumentException("Unknown process: " + process);
23444                 }
23445
23446                 if (start) {
23447                     stopProfilerLocked(null, 0);
23448                     setProfileApp(proc.info, proc.processName, profilerInfo);
23449                     mProfileProc = proc;
23450                     mProfileType = profileType;
23451                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23452                     try {
23453                         fd = fd.dup();
23454                     } catch (IOException e) {
23455                         fd = null;
23456                     }
23457                     profilerInfo.profileFd = fd;
23458                     proc.thread.profilerControl(start, profilerInfo, profileType);
23459                     fd = null;
23460                     try {
23461                         mProfilerInfo.profileFd.close();
23462                     } catch (IOException e) {
23463                     }
23464                     mProfilerInfo.profileFd = null;
23465                 } else {
23466                     stopProfilerLocked(proc, profileType);
23467                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23468                         try {
23469                             profilerInfo.profileFd.close();
23470                         } catch (IOException e) {
23471                         }
23472                     }
23473                 }
23474
23475                 return true;
23476             }
23477         } catch (RemoteException e) {
23478             throw new IllegalStateException("Process disappeared");
23479         } finally {
23480             if (profilerInfo != null && profilerInfo.profileFd != null) {
23481                 try {
23482                     profilerInfo.profileFd.close();
23483                 } catch (IOException e) {
23484                 }
23485             }
23486         }
23487     }
23488
23489     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23490         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23491                 userId, true, ALLOW_FULL_ONLY, callName, null);
23492         ProcessRecord proc = null;
23493         try {
23494             int pid = Integer.parseInt(process);
23495             synchronized (mPidsSelfLocked) {
23496                 proc = mPidsSelfLocked.get(pid);
23497             }
23498         } catch (NumberFormatException e) {
23499         }
23500
23501         if (proc == null) {
23502             ArrayMap<String, SparseArray<ProcessRecord>> all
23503                     = mProcessNames.getMap();
23504             SparseArray<ProcessRecord> procs = all.get(process);
23505             if (procs != null && procs.size() > 0) {
23506                 proc = procs.valueAt(0);
23507                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23508                     for (int i=1; i<procs.size(); i++) {
23509                         ProcessRecord thisProc = procs.valueAt(i);
23510                         if (thisProc.userId == userId) {
23511                             proc = thisProc;
23512                             break;
23513                         }
23514                     }
23515                 }
23516             }
23517         }
23518
23519         return proc;
23520     }
23521
23522     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23523             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23524
23525         try {
23526             synchronized (this) {
23527                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23528                 // its own permission (same as profileControl).
23529                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23530                         != PackageManager.PERMISSION_GRANTED) {
23531                     throw new SecurityException("Requires permission "
23532                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23533                 }
23534
23535                 if (fd == null) {
23536                     throw new IllegalArgumentException("null fd");
23537                 }
23538
23539                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23540                 if (proc == null || proc.thread == null) {
23541                     throw new IllegalArgumentException("Unknown process: " + process);
23542                 }
23543
23544                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23545                 if (!isDebuggable) {
23546                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23547                         throw new SecurityException("Process not debuggable: " + proc);
23548                     }
23549                 }
23550
23551                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23552                 fd = null;
23553                 return true;
23554             }
23555         } catch (RemoteException e) {
23556             throw new IllegalStateException("Process disappeared");
23557         } finally {
23558             if (fd != null) {
23559                 try {
23560                     fd.close();
23561                 } catch (IOException e) {
23562                 }
23563             }
23564         }
23565     }
23566
23567     @Override
23568     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23569             String reportPackage) {
23570         if (processName != null) {
23571             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23572                     "setDumpHeapDebugLimit()");
23573         } else {
23574             synchronized (mPidsSelfLocked) {
23575                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23576                 if (proc == null) {
23577                     throw new SecurityException("No process found for calling pid "
23578                             + Binder.getCallingPid());
23579                 }
23580                 if (!Build.IS_DEBUGGABLE
23581                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23582                     throw new SecurityException("Not running a debuggable build");
23583                 }
23584                 processName = proc.processName;
23585                 uid = proc.uid;
23586                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23587                     throw new SecurityException("Package " + reportPackage + " is not running in "
23588                             + proc);
23589                 }
23590             }
23591         }
23592         synchronized (this) {
23593             if (maxMemSize > 0) {
23594                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23595             } else {
23596                 if (uid != 0) {
23597                     mMemWatchProcesses.remove(processName, uid);
23598                 } else {
23599                     mMemWatchProcesses.getMap().remove(processName);
23600                 }
23601             }
23602         }
23603     }
23604
23605     @Override
23606     public void dumpHeapFinished(String path) {
23607         synchronized (this) {
23608             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23609                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23610                         + " does not match last pid " + mMemWatchDumpPid);
23611                 return;
23612             }
23613             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23614                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23615                         + " does not match last path " + mMemWatchDumpFile);
23616                 return;
23617             }
23618             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23619             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23620
23621             // Forced gc to clean up the remnant hprof fd.
23622             Runtime.getRuntime().gc();
23623         }
23624     }
23625
23626     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23627     public void monitor() {
23628         synchronized (this) { }
23629     }
23630
23631     void onCoreSettingsChange(Bundle settings) {
23632         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23633             ProcessRecord processRecord = mLruProcesses.get(i);
23634             try {
23635                 if (processRecord.thread != null) {
23636                     processRecord.thread.setCoreSettings(settings);
23637                 }
23638             } catch (RemoteException re) {
23639                 /* ignore */
23640             }
23641         }
23642     }
23643
23644     // Multi-user methods
23645
23646     /**
23647      * Start user, if its not already running, but don't bring it to foreground.
23648      */
23649     @Override
23650     public boolean startUserInBackground(final int userId) {
23651         return mUserController.startUser(userId, /* foreground */ false);
23652     }
23653
23654     @Override
23655     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23656         return mUserController.unlockUser(userId, token, secret, listener);
23657     }
23658
23659     @Override
23660     public boolean switchUser(final int targetUserId) {
23661         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23662         int currentUserId;
23663         UserInfo targetUserInfo;
23664         synchronized (this) {
23665             currentUserId = mUserController.getCurrentUserIdLocked();
23666             targetUserInfo = mUserController.getUserInfo(targetUserId);
23667             if (targetUserId == currentUserId) {
23668                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23669                 return true;
23670             }
23671             if (targetUserInfo == null) {
23672                 Slog.w(TAG, "No user info for user #" + targetUserId);
23673                 return false;
23674             }
23675             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23676                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23677                         + " when device is in demo mode");
23678                 return false;
23679             }
23680             if (!targetUserInfo.supportsSwitchTo()) {
23681                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23682                 return false;
23683             }
23684             if (targetUserInfo.isManagedProfile()) {
23685                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23686                 return false;
23687             }
23688             mUserController.setTargetUserIdLocked(targetUserId);
23689         }
23690         if (mUserController.mUserSwitchUiEnabled) {
23691             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23692             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23693             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23694             mUiHandler.sendMessage(mHandler.obtainMessage(
23695                     START_USER_SWITCH_UI_MSG, userNames));
23696         } else {
23697             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23698             mHandler.sendMessage(mHandler.obtainMessage(
23699                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23700         }
23701         return true;
23702     }
23703
23704     void scheduleStartProfilesLocked() {
23705         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23706             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23707                     DateUtils.SECOND_IN_MILLIS);
23708         }
23709     }
23710
23711     @Override
23712     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23713         return mUserController.stopUser(userId, force, callback);
23714     }
23715
23716     @Override
23717     public UserInfo getCurrentUser() {
23718         return mUserController.getCurrentUser();
23719     }
23720
23721     String getStartedUserState(int userId) {
23722         synchronized (this) {
23723             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23724             return UserState.stateToString(userState.state);
23725         }
23726     }
23727
23728     @Override
23729     public boolean isUserRunning(int userId, int flags) {
23730         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23731                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23732                     != PackageManager.PERMISSION_GRANTED) {
23733             String msg = "Permission Denial: isUserRunning() from pid="
23734                     + Binder.getCallingPid()
23735                     + ", uid=" + Binder.getCallingUid()
23736                     + " requires " + INTERACT_ACROSS_USERS;
23737             Slog.w(TAG, msg);
23738             throw new SecurityException(msg);
23739         }
23740         synchronized (this) {
23741             return mUserController.isUserRunningLocked(userId, flags);
23742         }
23743     }
23744
23745     @Override
23746     public int[] getRunningUserIds() {
23747         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23748                 != PackageManager.PERMISSION_GRANTED) {
23749             String msg = "Permission Denial: isUserRunning() from pid="
23750                     + Binder.getCallingPid()
23751                     + ", uid=" + Binder.getCallingUid()
23752                     + " requires " + INTERACT_ACROSS_USERS;
23753             Slog.w(TAG, msg);
23754             throw new SecurityException(msg);
23755         }
23756         synchronized (this) {
23757             return mUserController.getStartedUserArrayLocked();
23758         }
23759     }
23760
23761     @Override
23762     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23763         mUserController.registerUserSwitchObserver(observer, name);
23764     }
23765
23766     @Override
23767     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23768         mUserController.unregisterUserSwitchObserver(observer);
23769     }
23770
23771     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23772         if (info == null) return null;
23773         ApplicationInfo newInfo = new ApplicationInfo(info);
23774         newInfo.initForUser(userId);
23775         return newInfo;
23776     }
23777
23778     public boolean isUserStopped(int userId) {
23779         synchronized (this) {
23780             return mUserController.getStartedUserStateLocked(userId) == null;
23781         }
23782     }
23783
23784     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23785         if (aInfo == null
23786                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23787             return aInfo;
23788         }
23789
23790         ActivityInfo info = new ActivityInfo(aInfo);
23791         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23792         return info;
23793     }
23794
23795     private boolean processSanityChecksLocked(ProcessRecord process) {
23796         if (process == null || process.thread == null) {
23797             return false;
23798         }
23799
23800         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23801         if (!isDebuggable) {
23802             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23803                 return false;
23804             }
23805         }
23806
23807         return true;
23808     }
23809
23810     public boolean startBinderTracking() throws RemoteException {
23811         synchronized (this) {
23812             mBinderTransactionTrackingEnabled = true;
23813             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23814             // permission (same as profileControl).
23815             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23816                     != PackageManager.PERMISSION_GRANTED) {
23817                 throw new SecurityException("Requires permission "
23818                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23819             }
23820
23821             for (int i = 0; i < mLruProcesses.size(); i++) {
23822                 ProcessRecord process = mLruProcesses.get(i);
23823                 if (!processSanityChecksLocked(process)) {
23824                     continue;
23825                 }
23826                 try {
23827                     process.thread.startBinderTracking();
23828                 } catch (RemoteException e) {
23829                     Log.v(TAG, "Process disappared");
23830                 }
23831             }
23832             return true;
23833         }
23834     }
23835
23836     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23837         try {
23838             synchronized (this) {
23839                 mBinderTransactionTrackingEnabled = false;
23840                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23841                 // permission (same as profileControl).
23842                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23843                         != PackageManager.PERMISSION_GRANTED) {
23844                     throw new SecurityException("Requires permission "
23845                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23846                 }
23847
23848                 if (fd == null) {
23849                     throw new IllegalArgumentException("null fd");
23850                 }
23851
23852                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23853                 pw.println("Binder transaction traces for all processes.\n");
23854                 for (ProcessRecord process : mLruProcesses) {
23855                     if (!processSanityChecksLocked(process)) {
23856                         continue;
23857                     }
23858
23859                     pw.println("Traces for process: " + process.processName);
23860                     pw.flush();
23861                     try {
23862                         TransferPipe tp = new TransferPipe();
23863                         try {
23864                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23865                             tp.go(fd.getFileDescriptor());
23866                         } finally {
23867                             tp.kill();
23868                         }
23869                     } catch (IOException e) {
23870                         pw.println("Failure while dumping IPC traces from " + process +
23871                                 ".  Exception: " + e);
23872                         pw.flush();
23873                     } catch (RemoteException e) {
23874                         pw.println("Got a RemoteException while dumping IPC traces from " +
23875                                 process + ".  Exception: " + e);
23876                         pw.flush();
23877                     }
23878                 }
23879                 fd = null;
23880                 return true;
23881             }
23882         } finally {
23883             if (fd != null) {
23884                 try {
23885                     fd.close();
23886                 } catch (IOException e) {
23887                 }
23888             }
23889         }
23890     }
23891
23892     @VisibleForTesting
23893     final class LocalService extends ActivityManagerInternal {
23894         @Override
23895         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23896                 int targetUserId) {
23897             synchronized (ActivityManagerService.this) {
23898                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23899                         targetPkg, intent, null, targetUserId);
23900             }
23901         }
23902
23903         @Override
23904         public String checkContentProviderAccess(String authority, int userId) {
23905             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23906         }
23907
23908         @Override
23909         public void onWakefulnessChanged(int wakefulness) {
23910             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23911         }
23912
23913         @Override
23914         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23915                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23916             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23917                     processName, abiOverride, uid, crashHandler);
23918         }
23919
23920         @Override
23921         public SleepToken acquireSleepToken(String tag, int displayId) {
23922             Preconditions.checkNotNull(tag);
23923             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23924         }
23925
23926         @Override
23927         public ComponentName getHomeActivityForUser(int userId) {
23928             synchronized (ActivityManagerService.this) {
23929                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23930                 return homeActivity == null ? null : homeActivity.realActivity;
23931             }
23932         }
23933
23934         @Override
23935         public void onUserRemoved(int userId) {
23936             synchronized (ActivityManagerService.this) {
23937                 ActivityManagerService.this.onUserStoppedLocked(userId);
23938             }
23939             mBatteryStatsService.onUserRemoved(userId);
23940         }
23941
23942         @Override
23943         public void onLocalVoiceInteractionStarted(IBinder activity,
23944                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23945             synchronized (ActivityManagerService.this) {
23946                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23947                         voiceSession, voiceInteractor);
23948             }
23949         }
23950
23951         @Override
23952         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23953             synchronized (ActivityManagerService.this) {
23954                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23955                         reasons, timestamp);
23956             }
23957         }
23958
23959         @Override
23960         public void notifyAppTransitionFinished() {
23961             synchronized (ActivityManagerService.this) {
23962                 mStackSupervisor.notifyAppTransitionDone();
23963             }
23964         }
23965
23966         @Override
23967         public void notifyAppTransitionCancelled() {
23968             synchronized (ActivityManagerService.this) {
23969                 mStackSupervisor.notifyAppTransitionDone();
23970             }
23971         }
23972
23973         @Override
23974         public List<IBinder> getTopVisibleActivities() {
23975             synchronized (ActivityManagerService.this) {
23976                 return mStackSupervisor.getTopVisibleActivities();
23977             }
23978         }
23979
23980         @Override
23981         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23982             synchronized (ActivityManagerService.this) {
23983                 mStackSupervisor.setDockedStackMinimized(minimized);
23984             }
23985         }
23986
23987         @Override
23988         public void killForegroundAppsForUser(int userHandle) {
23989             synchronized (ActivityManagerService.this) {
23990                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23991                 final int NP = mProcessNames.getMap().size();
23992                 for (int ip = 0; ip < NP; ip++) {
23993                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23994                     final int NA = apps.size();
23995                     for (int ia = 0; ia < NA; ia++) {
23996                         final ProcessRecord app = apps.valueAt(ia);
23997                         if (app.persistent) {
23998                             // We don't kill persistent processes.
23999                             continue;
24000                         }
24001                         if (app.removed) {
24002                             procs.add(app);
24003                         } else if (app.userId == userHandle && app.foregroundActivities) {
24004                             app.removed = true;
24005                             procs.add(app);
24006                         }
24007                     }
24008                 }
24009
24010                 final int N = procs.size();
24011                 for (int i = 0; i < N; i++) {
24012                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
24013                 }
24014             }
24015         }
24016
24017         @Override
24018         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24019                 long duration) {
24020             if (!(target instanceof PendingIntentRecord)) {
24021                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24022                 return;
24023             }
24024             synchronized (ActivityManagerService.this) {
24025                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24026             }
24027         }
24028
24029         @Override
24030         public void setDeviceIdleWhitelist(int[] appids) {
24031             synchronized (ActivityManagerService.this) {
24032                 mDeviceIdleWhitelist = appids;
24033             }
24034         }
24035
24036         @Override
24037         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24038             synchronized (ActivityManagerService.this) {
24039                 mDeviceIdleTempWhitelist = appids;
24040                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24041             }
24042         }
24043
24044         @Override
24045         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24046                 int userId) {
24047             Preconditions.checkNotNull(values, "Configuration must not be null");
24048             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24049             synchronized (ActivityManagerService.this) {
24050                 updateConfigurationLocked(values, null, false, true, userId,
24051                         false /* deferResume */);
24052             }
24053         }
24054
24055         @Override
24056         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24057                 Bundle bOptions) {
24058             Preconditions.checkNotNull(intents, "intents");
24059             final String[] resolvedTypes = new String[intents.length];
24060             for (int i = 0; i < intents.length; i++) {
24061                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24062             }
24063
24064             // UID of the package on user userId.
24065             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24066             // packageUid may not be initialized.
24067             int packageUid = 0;
24068             try {
24069                 packageUid = AppGlobals.getPackageManager().getPackageUid(
24070                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24071             } catch (RemoteException e) {
24072                 // Shouldn't happen.
24073             }
24074
24075             synchronized (ActivityManagerService.this) {
24076                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24077                         /*resultTo*/ null, bOptions, userId);
24078             }
24079         }
24080
24081         @Override
24082         public int getUidProcessState(int uid) {
24083             return getUidState(uid);
24084         }
24085
24086         @Override
24087         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24088             synchronized (ActivityManagerService.this) {
24089
24090                 // We might change the visibilities here, so prepare an empty app transition which
24091                 // might be overridden later if we actually change visibilities.
24092                 final boolean wasTransitionSet =
24093                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24094                 if (!wasTransitionSet) {
24095                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24096                             false /* alwaysKeepCurrent */);
24097                 }
24098                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24099
24100                 // If there was a transition set already we don't want to interfere with it as we
24101                 // might be starting it too early.
24102                 if (!wasTransitionSet) {
24103                     mWindowManager.executeAppTransition();
24104                 }
24105             }
24106             if (callback != null) {
24107                 callback.run();
24108             }
24109         }
24110
24111         @Override
24112         public boolean isSystemReady() {
24113             // no need to synchronize(this) just to read & return the value
24114             return mSystemReady;
24115         }
24116
24117         @Override
24118         public void notifyKeyguardTrustedChanged() {
24119             synchronized (ActivityManagerService.this) {
24120                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24121                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24122                 }
24123             }
24124         }
24125
24126         /**
24127          * Sets if the given pid has an overlay UI or not.
24128          *
24129          * @param pid The pid we are setting overlay UI for.
24130          * @param hasOverlayUi True if the process has overlay UI.
24131          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24132          */
24133         @Override
24134         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24135             synchronized (ActivityManagerService.this) {
24136                 final ProcessRecord pr;
24137                 synchronized (mPidsSelfLocked) {
24138                     pr = mPidsSelfLocked.get(pid);
24139                     if (pr == null) {
24140                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24141                         return;
24142                     }
24143                 }
24144                 if (pr.hasOverlayUi == hasOverlayUi) {
24145                     return;
24146                 }
24147                 pr.hasOverlayUi = hasOverlayUi;
24148                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24149                 updateOomAdjLocked(pr, true);
24150             }
24151         }
24152
24153         /**
24154          * Called after the network policy rules are updated by
24155          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24156          * and {@param procStateSeq}.
24157          */
24158         @Override
24159         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24160             if (DEBUG_NETWORK) {
24161                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24162                         + uid + " seq: " + procStateSeq);
24163             }
24164             UidRecord record;
24165             synchronized (ActivityManagerService.this) {
24166                 record = mActiveUids.get(uid);
24167                 if (record == null) {
24168                     if (DEBUG_NETWORK) {
24169                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24170                                 + " procStateSeq: " + procStateSeq);
24171                     }
24172                     return;
24173                 }
24174             }
24175             synchronized (record.networkStateLock) {
24176                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24177                     if (DEBUG_NETWORK) {
24178                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24179                                 + " been handled for uid: " + uid);
24180                     }
24181                     return;
24182                 }
24183                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24184                 if (record.curProcStateSeq > procStateSeq) {
24185                     if (DEBUG_NETWORK) {
24186                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24187                                 + ", curProcstateSeq: " + record.curProcStateSeq
24188                                 + ", procStateSeq: " + procStateSeq);
24189                     }
24190                     return;
24191                 }
24192                 if (record.waitingForNetwork) {
24193                     if (DEBUG_NETWORK) {
24194                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24195                                 + ", procStateSeq: " + procStateSeq);
24196                     }
24197                     record.networkStateLock.notifyAll();
24198                 }
24199             }
24200         }
24201
24202         /**
24203          * Called after virtual display Id is updated by
24204          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24205          * {@param vrVr2dDisplayId}.
24206          */
24207         @Override
24208         public void setVr2dDisplayId(int vr2dDisplayId) {
24209             if (DEBUG_STACK) {
24210                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24211                         vr2dDisplayId);
24212             }
24213             synchronized (ActivityManagerService.this) {
24214                 mVr2dDisplayId = vr2dDisplayId;
24215             }
24216         }
24217
24218         @Override
24219         public void saveANRState(String reason) {
24220             synchronized (ActivityManagerService.this) {
24221                 final StringWriter sw = new StringWriter();
24222                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24223                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24224                 if (reason != null) {
24225                     pw.println("  Reason: " + reason);
24226                 }
24227                 pw.println();
24228                 mActivityStarter.dump(pw, "  ", null);
24229                 pw.println();
24230                 pw.println("-------------------------------------------------------------------------------");
24231                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24232                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24233                         "" /* header */);
24234                 pw.println();
24235                 pw.close();
24236
24237                 mLastANRState = sw.toString();
24238             }
24239         }
24240
24241         @Override
24242         public void clearSavedANRState() {
24243             synchronized (ActivityManagerService.this) {
24244                 mLastANRState = null;
24245             }
24246         }
24247
24248         @Override
24249         public void setFocusedActivity(IBinder token) {
24250             synchronized (ActivityManagerService.this) {
24251                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24252                 if (r == null) {
24253                     throw new IllegalArgumentException(
24254                             "setFocusedActivity: No activity record matching token=" + token);
24255                 }
24256                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24257                         r, "setFocusedActivity")) {
24258                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
24259                 }
24260             }
24261         }
24262
24263         @Override
24264         public void registerScreenObserver(ScreenObserver observer) {
24265             mScreenObservers.add(observer);
24266         }
24267     }
24268
24269     /**
24270      * Called by app main thread to wait for the network policy rules to get updated.
24271      *
24272      * @param procStateSeq The sequence number indicating the process state change that the main
24273      *                     thread is interested in.
24274      */
24275     @Override
24276     public void waitForNetworkStateUpdate(long procStateSeq) {
24277         final int callingUid = Binder.getCallingUid();
24278         if (DEBUG_NETWORK) {
24279             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24280         }
24281         UidRecord record;
24282         synchronized (this) {
24283             record = mActiveUids.get(callingUid);
24284             if (record == null) {
24285                 return;
24286             }
24287         }
24288         synchronized (record.networkStateLock) {
24289             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24290                 if (DEBUG_NETWORK) {
24291                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24292                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24293                             + " lastProcStateSeqDispatchedToObservers: "
24294                             + record.lastDispatchedProcStateSeq);
24295                 }
24296                 return;
24297             }
24298             if (record.curProcStateSeq > procStateSeq) {
24299                 if (DEBUG_NETWORK) {
24300                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24301                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24302                             + ", procStateSeq: " + procStateSeq);
24303                 }
24304                 return;
24305             }
24306             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24307                 if (DEBUG_NETWORK) {
24308                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24309                             + procStateSeq + ", so no need to wait. Uid: "
24310                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24311                             + record.lastNetworkUpdatedProcStateSeq);
24312                 }
24313                 return;
24314             }
24315             try {
24316                 if (DEBUG_NETWORK) {
24317                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24318                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24319                 }
24320                 final long startTime = SystemClock.uptimeMillis();
24321                 record.waitingForNetwork = true;
24322                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24323                 record.waitingForNetwork = false;
24324                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24325                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24326                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24327                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24328                             + procStateSeq + " UidRec: " + record
24329                             + " validateUidRec: " + mValidateUids.get(callingUid));
24330                 }
24331             } catch (InterruptedException e) {
24332                 Thread.currentThread().interrupt();
24333             }
24334         }
24335     }
24336
24337     public void waitForBroadcastIdle(PrintWriter pw) {
24338         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24339         while (true) {
24340             boolean idle = true;
24341             synchronized (this) {
24342                 for (BroadcastQueue queue : mBroadcastQueues) {
24343                     if (!queue.isIdle()) {
24344                         final String msg = "Waiting for queue " + queue + " to become idle...";
24345                         pw.println(msg);
24346                         pw.flush();
24347                         Slog.v(TAG, msg);
24348                         idle = false;
24349                     }
24350                 }
24351             }
24352
24353             if (idle) {
24354                 final String msg = "All broadcast queues are idle!";
24355                 pw.println(msg);
24356                 pw.flush();
24357                 Slog.v(TAG, msg);
24358                 return;
24359             } else {
24360                 SystemClock.sleep(1000);
24361             }
24362         }
24363     }
24364
24365     /**
24366      * Return the user id of the last resumed activity.
24367      */
24368     @Override
24369     public @UserIdInt int getLastResumedActivityUserId() {
24370         enforceCallingPermission(
24371                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24372         synchronized (this) {
24373             if (mLastResumedActivity == null) {
24374                 return mUserController.getCurrentUserIdLocked();
24375             }
24376             return mLastResumedActivity.userId;
24377         }
24378     }
24379
24380     /**
24381      * An implementation of IAppTask, that allows an app to manage its own tasks via
24382      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24383      * only the process that calls getAppTasks() can call the AppTask methods.
24384      */
24385     class AppTaskImpl extends IAppTask.Stub {
24386         private int mTaskId;
24387         private int mCallingUid;
24388
24389         public AppTaskImpl(int taskId, int callingUid) {
24390             mTaskId = taskId;
24391             mCallingUid = callingUid;
24392         }
24393
24394         private void checkCaller() {
24395             if (mCallingUid != Binder.getCallingUid()) {
24396                 throw new SecurityException("Caller " + mCallingUid
24397                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24398             }
24399         }
24400
24401         @Override
24402         public void finishAndRemoveTask() {
24403             checkCaller();
24404
24405             synchronized (ActivityManagerService.this) {
24406                 long origId = Binder.clearCallingIdentity();
24407                 try {
24408                     // We remove the task from recents to preserve backwards
24409                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24410                             REMOVE_FROM_RECENTS)) {
24411                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24412                     }
24413                 } finally {
24414                     Binder.restoreCallingIdentity(origId);
24415                 }
24416             }
24417         }
24418
24419         @Override
24420         public ActivityManager.RecentTaskInfo getTaskInfo() {
24421             checkCaller();
24422
24423             synchronized (ActivityManagerService.this) {
24424                 long origId = Binder.clearCallingIdentity();
24425                 try {
24426                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24427                     if (tr == null) {
24428                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24429                     }
24430                     return createRecentTaskInfoFromTaskRecord(tr);
24431                 } finally {
24432                     Binder.restoreCallingIdentity(origId);
24433                 }
24434             }
24435         }
24436
24437         @Override
24438         public void moveToFront() {
24439             checkCaller();
24440             // Will bring task to front if it already has a root activity.
24441             final long origId = Binder.clearCallingIdentity();
24442             try {
24443                 synchronized (this) {
24444                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24445                 }
24446             } finally {
24447                 Binder.restoreCallingIdentity(origId);
24448             }
24449         }
24450
24451         @Override
24452         public int startActivity(IBinder whoThread, String callingPackage,
24453                 Intent intent, String resolvedType, Bundle bOptions) {
24454             checkCaller();
24455
24456             int callingUser = UserHandle.getCallingUserId();
24457             TaskRecord tr;
24458             IApplicationThread appThread;
24459             synchronized (ActivityManagerService.this) {
24460                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24461                 if (tr == null) {
24462                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24463                 }
24464                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24465                 if (appThread == null) {
24466                     throw new IllegalArgumentException("Bad app thread " + appThread);
24467                 }
24468             }
24469             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24470                     resolvedType, null, null, null, null, 0, 0, null, null,
24471                     null, bOptions, false, callingUser, tr, "AppTaskImpl");
24472         }
24473
24474         @Override
24475         public void setExcludeFromRecents(boolean exclude) {
24476             checkCaller();
24477
24478             synchronized (ActivityManagerService.this) {
24479                 long origId = Binder.clearCallingIdentity();
24480                 try {
24481                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24482                     if (tr == null) {
24483                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24484                     }
24485                     Intent intent = tr.getBaseIntent();
24486                     if (exclude) {
24487                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24488                     } else {
24489                         intent.setFlags(intent.getFlags()
24490                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24491                     }
24492                 } finally {
24493                     Binder.restoreCallingIdentity(origId);
24494                 }
24495             }
24496         }
24497     }
24498
24499     /**
24500      * Kill processes for the user with id userId and that depend on the package named packageName
24501      */
24502     @Override
24503     public void killPackageDependents(String packageName, int userId) {
24504         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24505         if (packageName == null) {
24506             throw new NullPointerException(
24507                     "Cannot kill the dependents of a package without its name.");
24508         }
24509
24510         long callingId = Binder.clearCallingIdentity();
24511         IPackageManager pm = AppGlobals.getPackageManager();
24512         int pkgUid = -1;
24513         try {
24514             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24515         } catch (RemoteException e) {
24516         }
24517         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24518             throw new IllegalArgumentException(
24519                     "Cannot kill dependents of non-existing package " + packageName);
24520         }
24521         try {
24522             synchronized(this) {
24523                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24524                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24525                         "dep: " + packageName);
24526             }
24527         } finally {
24528             Binder.restoreCallingIdentity(callingId);
24529         }
24530     }
24531
24532     @Override
24533     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24534             throws RemoteException {
24535         final long callingId = Binder.clearCallingIdentity();
24536         try {
24537             mKeyguardController.dismissKeyguard(token, callback);
24538         } finally {
24539             Binder.restoreCallingIdentity(callingId);
24540         }
24541     }
24542
24543     @Override
24544     public int restartUserInBackground(final int userId) {
24545         return mUserController.restartUser(userId, /* foreground */ false);
24546     }
24547
24548     @Override
24549     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24550         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24551                 "scheduleApplicationInfoChanged()");
24552
24553         synchronized (this) {
24554             final long origId = Binder.clearCallingIdentity();
24555             try {
24556                 updateApplicationInfoLocked(packageNames, userId);
24557             } finally {
24558                 Binder.restoreCallingIdentity(origId);
24559             }
24560         }
24561     }
24562
24563     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24564         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24565         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24566             final ProcessRecord app = mLruProcesses.get(i);
24567             if (app.thread == null) {
24568                 continue;
24569             }
24570
24571             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24572                 continue;
24573             }
24574
24575             final int packageCount = app.pkgList.size();
24576             for (int j = 0; j < packageCount; j++) {
24577                 final String packageName = app.pkgList.keyAt(j);
24578                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24579                     try {
24580                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24581                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24582                         if (ai != null) {
24583                             app.thread.scheduleApplicationInfoChanged(ai);
24584                         }
24585                     } catch (RemoteException e) {
24586                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24587                                     packageName, app));
24588                     }
24589                 }
24590             }
24591         }
24592     }
24593
24594     /**
24595      * Attach an agent to the specified process (proces name or PID)
24596      */
24597     public void attachAgent(String process, String path) {
24598         try {
24599             synchronized (this) {
24600                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24601                 if (proc == null || proc.thread == null) {
24602                     throw new IllegalArgumentException("Unknown process: " + process);
24603                 }
24604
24605                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24606                 if (!isDebuggable) {
24607                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24608                         throw new SecurityException("Process not debuggable: " + proc);
24609                     }
24610                 }
24611
24612                 proc.thread.attachAgent(path);
24613             }
24614         } catch (RemoteException e) {
24615             throw new IllegalStateException("Process disappeared");
24616         }
24617     }
24618
24619     @VisibleForTesting
24620     public static class Injector {
24621         private NetworkManagementInternal mNmi;
24622
24623         public Context getContext() {
24624             return null;
24625         }
24626
24627         public AppOpsService getAppOpsService(File file, Handler handler) {
24628             return new AppOpsService(file, handler);
24629         }
24630
24631         public Handler getUiHandler(ActivityManagerService service) {
24632             return service.new UiHandler();
24633         }
24634
24635         public boolean isNetworkRestrictedForUid(int uid) {
24636             if (ensureHasNetworkManagementInternal()) {
24637                 return mNmi.isNetworkRestrictedForUid(uid);
24638             }
24639             return false;
24640         }
24641
24642         private boolean ensureHasNetworkManagementInternal() {
24643             if (mNmi == null) {
24644                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24645             }
24646             return mNmi != null;
24647         }
24648     }
24649
24650     @Override
24651     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24652             throws RemoteException {
24653         synchronized (this) {
24654             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24655             if (r == null) {
24656                 return;
24657             }
24658             final long origId = Binder.clearCallingIdentity();
24659             try {
24660                 r.setShowWhenLocked(showWhenLocked);
24661             } finally {
24662                 Binder.restoreCallingIdentity(origId);
24663             }
24664         }
24665     }
24666
24667     @Override
24668     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24669         synchronized (this) {
24670             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24671             if (r == null) {
24672                 return;
24673             }
24674             final long origId = Binder.clearCallingIdentity();
24675             try {
24676                 r.setTurnScreenOn(turnScreenOn);
24677             } finally {
24678                 Binder.restoreCallingIdentity(origId);
24679             }
24680         }
24681     }
24682 }