OSDN Git Service

Merge "Fix NPE by pressing Volume Up/Down"
[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             String invokeWith = null;
3881             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3882                 // Debuggable apps may include a wrapper script with their library directory.
3883                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3884                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3885                 try {
3886                     if (new File(wrapperFileName).exists()) {
3887                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3888                     }
3889                 } finally {
3890                     StrictMode.setThreadPolicy(oldPolicy);
3891                 }
3892             }
3893
3894             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3895             if (requiredAbi == null) {
3896                 requiredAbi = Build.SUPPORTED_ABIS[0];
3897             }
3898
3899             String instructionSet = null;
3900             if (app.info.primaryCpuAbi != null) {
3901                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3902             }
3903
3904             app.gids = gids;
3905             app.requiredAbi = requiredAbi;
3906             app.instructionSet = instructionSet;
3907
3908             // the per-user SELinux context must be set
3909             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3910                 Slog.wtf(TAG, "SELinux tag not defined",
3911                         new IllegalStateException("SELinux tag not defined for "
3912                         + app.info.packageName + " (uid " + app.uid + ")"));
3913             }
3914             final String seInfo = app.info.seInfo
3915                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3916             // Start the process.  It will either succeed and return a result containing
3917             // the PID of the new process, or else throw a RuntimeException.
3918             boolean isActivityProcess = (entryPoint == null);
3919             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3920             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3921                     app.processName);
3922             checkTime(startTime, "startProcess: asking zygote to start proc");
3923             ProcessStartResult startResult;
3924             if (hostingType.equals("webview_service")) {
3925                 startResult = startWebView(entryPoint,
3926                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3927                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3928                         app.info.dataDir, null, entryPointArgs);
3929             } else {
3930                 startResult = Process.start(entryPoint,
3931                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3932                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933                         app.info.dataDir, invokeWith, entryPointArgs);
3934             }
3935             checkTime(startTime, "startProcess: returned from zygote!");
3936             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3937
3938             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3939             checkTime(startTime, "startProcess: done updating battery stats");
3940
3941             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3942                     UserHandle.getUserId(uid), startResult.pid, uid,
3943                     app.processName, hostingType,
3944                     hostingNameStr != null ? hostingNameStr : "");
3945
3946             try {
3947                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3948                         seInfo, app.info.sourceDir, startResult.pid);
3949             } catch (RemoteException ex) {
3950                 // Ignore
3951             }
3952
3953             if (app.persistent) {
3954                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3955             }
3956
3957             checkTime(startTime, "startProcess: building log message");
3958             StringBuilder buf = mStringBuilder;
3959             buf.setLength(0);
3960             buf.append("Start proc ");
3961             buf.append(startResult.pid);
3962             buf.append(':');
3963             buf.append(app.processName);
3964             buf.append('/');
3965             UserHandle.formatUid(buf, uid);
3966             if (!isActivityProcess) {
3967                 buf.append(" [");
3968                 buf.append(entryPoint);
3969                 buf.append("]");
3970             }
3971             buf.append(" for ");
3972             buf.append(hostingType);
3973             if (hostingNameStr != null) {
3974                 buf.append(" ");
3975                 buf.append(hostingNameStr);
3976             }
3977             Slog.i(TAG, buf.toString());
3978             app.setPid(startResult.pid);
3979             app.usingWrapper = startResult.usingWrapper;
3980             app.removed = false;
3981             app.killed = false;
3982             app.killedByAm = false;
3983             checkTime(startTime, "startProcess: starting to update pids map");
3984             ProcessRecord oldApp;
3985             synchronized (mPidsSelfLocked) {
3986                 oldApp = mPidsSelfLocked.get(startResult.pid);
3987             }
3988             // If there is already an app occupying that pid that hasn't been cleaned up
3989             if (oldApp != null && !app.isolated) {
3990                 // Clean up anything relating to this pid first
3991                 Slog.w(TAG, "Reusing pid " + startResult.pid
3992                         + " while app is still mapped to it");
3993                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3994                         true /*replacingPid*/);
3995             }
3996             synchronized (mPidsSelfLocked) {
3997                 this.mPidsSelfLocked.put(startResult.pid, app);
3998                 if (isActivityProcess) {
3999                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4000                     msg.obj = app;
4001                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4002                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4003                 }
4004             }
4005             checkTime(startTime, "startProcess: done updating pids map");
4006         } catch (RuntimeException e) {
4007             Slog.e(TAG, "Failure starting process " + app.processName, e);
4008
4009             // Something went very wrong while trying to start this process; one
4010             // common case is when the package is frozen due to an active
4011             // upgrade. To recover, clean up any active bookkeeping related to
4012             // starting this process. (We already invoked this method once when
4013             // the package was initially frozen through KILL_APPLICATION_MSG, so
4014             // it doesn't hurt to use it again.)
4015             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4016                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4017         }
4018     }
4019
4020     void updateUsageStats(ActivityRecord component, boolean resumed) {
4021         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4022                 "updateUsageStats: comp=" + component + "res=" + resumed);
4023         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4024         if (resumed) {
4025             if (mUsageStatsService != null) {
4026                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4027                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4028             }
4029             synchronized (stats) {
4030                 stats.noteActivityResumedLocked(component.app.uid);
4031             }
4032         } else {
4033             if (mUsageStatsService != null) {
4034                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4035                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4036             }
4037             synchronized (stats) {
4038                 stats.noteActivityPausedLocked(component.app.uid);
4039             }
4040         }
4041     }
4042
4043     Intent getHomeIntent() {
4044         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4045         intent.setComponent(mTopComponent);
4046         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4047         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4048             intent.addCategory(Intent.CATEGORY_HOME);
4049         }
4050         return intent;
4051     }
4052
4053     boolean startHomeActivityLocked(int userId, String reason) {
4054         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4055                 && mTopAction == null) {
4056             // We are running in factory test mode, but unable to find
4057             // the factory test app, so just sit around displaying the
4058             // error message and don't try to start anything.
4059             return false;
4060         }
4061         Intent intent = getHomeIntent();
4062         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4063         if (aInfo != null) {
4064             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4065             // Don't do this if the home app is currently being
4066             // instrumented.
4067             aInfo = new ActivityInfo(aInfo);
4068             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4069             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4070                     aInfo.applicationInfo.uid, true);
4071             if (app == null || app.instr == null) {
4072                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4073                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4074                 // For ANR debugging to verify if the user activity is the one that actually
4075                 // launched.
4076                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4077                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4078             }
4079         } else {
4080             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4081         }
4082
4083         return true;
4084     }
4085
4086     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4087         ActivityInfo ai = null;
4088         ComponentName comp = intent.getComponent();
4089         try {
4090             if (comp != null) {
4091                 // Factory test.
4092                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4093             } else {
4094                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4095                         intent,
4096                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4097                         flags, userId);
4098
4099                 if (info != null) {
4100                     ai = info.activityInfo;
4101                 }
4102             }
4103         } catch (RemoteException e) {
4104             // ignore
4105         }
4106
4107         return ai;
4108     }
4109
4110     /**
4111      * Starts the "new version setup screen" if appropriate.
4112      */
4113     void startSetupActivityLocked() {
4114         // Only do this once per boot.
4115         if (mCheckedForSetup) {
4116             return;
4117         }
4118
4119         // We will show this screen if the current one is a different
4120         // version than the last one shown, and we are not running in
4121         // low-level factory test mode.
4122         final ContentResolver resolver = mContext.getContentResolver();
4123         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4124                 Settings.Global.getInt(resolver,
4125                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4126             mCheckedForSetup = true;
4127
4128             // See if we should be showing the platform update setup UI.
4129             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4130             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4131                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4132             if (!ris.isEmpty()) {
4133                 final ResolveInfo ri = ris.get(0);
4134                 String vers = ri.activityInfo.metaData != null
4135                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4136                         : null;
4137                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4138                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4139                             Intent.METADATA_SETUP_VERSION);
4140                 }
4141                 String lastVers = Settings.Secure.getString(
4142                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4143                 if (vers != null && !vers.equals(lastVers)) {
4144                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4145                     intent.setComponent(new ComponentName(
4146                             ri.activityInfo.packageName, ri.activityInfo.name));
4147                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4148                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4149                             null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4150                 }
4151             }
4152         }
4153     }
4154
4155     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4156         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4157     }
4158
4159     void enforceNotIsolatedCaller(String caller) {
4160         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4161             throw new SecurityException("Isolated process not allowed to call " + caller);
4162         }
4163     }
4164
4165     void enforceShellRestriction(String restriction, int userHandle) {
4166         if (Binder.getCallingUid() == SHELL_UID) {
4167             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4168                 throw new SecurityException("Shell does not have permission to access user "
4169                         + userHandle);
4170             }
4171         }
4172     }
4173
4174     @Override
4175     public int getFrontActivityScreenCompatMode() {
4176         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4177         synchronized (this) {
4178             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4179         }
4180     }
4181
4182     @Override
4183     public void setFrontActivityScreenCompatMode(int mode) {
4184         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4185                 "setFrontActivityScreenCompatMode");
4186         synchronized (this) {
4187             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4188         }
4189     }
4190
4191     @Override
4192     public int getPackageScreenCompatMode(String packageName) {
4193         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4194         synchronized (this) {
4195             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4196         }
4197     }
4198
4199     @Override
4200     public void setPackageScreenCompatMode(String packageName, int mode) {
4201         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4202                 "setPackageScreenCompatMode");
4203         synchronized (this) {
4204             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4205         }
4206     }
4207
4208     @Override
4209     public boolean getPackageAskScreenCompat(String packageName) {
4210         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4211         synchronized (this) {
4212             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4213         }
4214     }
4215
4216     @Override
4217     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4218         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4219                 "setPackageAskScreenCompat");
4220         synchronized (this) {
4221             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4222         }
4223     }
4224
4225     private boolean hasUsageStatsPermission(String callingPackage) {
4226         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4227                 Binder.getCallingUid(), callingPackage);
4228         if (mode == AppOpsManager.MODE_DEFAULT) {
4229             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4230                     == PackageManager.PERMISSION_GRANTED;
4231         }
4232         return mode == AppOpsManager.MODE_ALLOWED;
4233     }
4234
4235     @Override
4236     public int getPackageProcessState(String packageName, String callingPackage) {
4237         if (!hasUsageStatsPermission(callingPackage)) {
4238             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4239                     "getPackageProcessState");
4240         }
4241
4242         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4243         synchronized (this) {
4244             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4245                 final ProcessRecord proc = mLruProcesses.get(i);
4246                 if (procState > proc.setProcState) {
4247                     if (proc.pkgList.containsKey(packageName) ||
4248                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4249                         procState = proc.setProcState;
4250                     }
4251                 }
4252             }
4253         }
4254         return procState;
4255     }
4256
4257     @Override
4258     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4259             throws RemoteException {
4260         synchronized (this) {
4261             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4262             if (app == null) {
4263                 throw new IllegalArgumentException("Unknown process: " + process);
4264             }
4265             if (app.thread == null) {
4266                 throw new IllegalArgumentException("Process has no app thread");
4267             }
4268             if (app.trimMemoryLevel >= level) {
4269                 throw new IllegalArgumentException(
4270                         "Unable to set a higher trim level than current level");
4271             }
4272             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4273                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4274                 throw new IllegalArgumentException("Unable to set a background trim level "
4275                     + "on a foreground process");
4276             }
4277             app.thread.scheduleTrimMemory(level);
4278             app.trimMemoryLevel = level;
4279             return true;
4280         }
4281     }
4282
4283     private void dispatchProcessesChanged() {
4284         int N;
4285         synchronized (this) {
4286             N = mPendingProcessChanges.size();
4287             if (mActiveProcessChanges.length < N) {
4288                 mActiveProcessChanges = new ProcessChangeItem[N];
4289             }
4290             mPendingProcessChanges.toArray(mActiveProcessChanges);
4291             mPendingProcessChanges.clear();
4292             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4293                     "*** Delivering " + N + " process changes");
4294         }
4295
4296         int i = mProcessObservers.beginBroadcast();
4297         while (i > 0) {
4298             i--;
4299             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4300             if (observer != null) {
4301                 try {
4302                     for (int j=0; j<N; j++) {
4303                         ProcessChangeItem item = mActiveProcessChanges[j];
4304                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4305                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4306                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4307                                     + item.uid + ": " + item.foregroundActivities);
4308                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4309                                     item.foregroundActivities);
4310                         }
4311                     }
4312                 } catch (RemoteException e) {
4313                 }
4314             }
4315         }
4316         mProcessObservers.finishBroadcast();
4317
4318         synchronized (this) {
4319             for (int j=0; j<N; j++) {
4320                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4321             }
4322         }
4323     }
4324
4325     private void dispatchProcessDied(int pid, int uid) {
4326         int i = mProcessObservers.beginBroadcast();
4327         while (i > 0) {
4328             i--;
4329             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4330             if (observer != null) {
4331                 try {
4332                     observer.onProcessDied(pid, uid);
4333                 } catch (RemoteException e) {
4334                 }
4335             }
4336         }
4337         mProcessObservers.finishBroadcast();
4338     }
4339
4340     @VisibleForTesting
4341     void dispatchUidsChanged() {
4342         int N;
4343         synchronized (this) {
4344             N = mPendingUidChanges.size();
4345             if (mActiveUidChanges.length < N) {
4346                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4347             }
4348             for (int i=0; i<N; i++) {
4349                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4350                 mActiveUidChanges[i] = change;
4351                 if (change.uidRecord != null) {
4352                     change.uidRecord.pendingChange = null;
4353                     change.uidRecord = null;
4354                 }
4355             }
4356             mPendingUidChanges.clear();
4357             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4358                     "*** Delivering " + N + " uid changes");
4359         }
4360
4361         int i = mUidObservers.beginBroadcast();
4362         while (i > 0) {
4363             i--;
4364             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4365                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4366         }
4367         mUidObservers.finishBroadcast();
4368
4369         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4370             for (int j = 0; j < N; ++j) {
4371                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4372                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4373                     mValidateUids.remove(item.uid);
4374                 } else {
4375                     UidRecord validateUid = mValidateUids.get(item.uid);
4376                     if (validateUid == null) {
4377                         validateUid = new UidRecord(item.uid);
4378                         mValidateUids.put(item.uid, validateUid);
4379                     }
4380                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4381                         validateUid.idle = true;
4382                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4383                         validateUid.idle = false;
4384                     }
4385                     validateUid.curProcState = validateUid.setProcState = item.processState;
4386                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4387                 }
4388             }
4389         }
4390
4391         synchronized (this) {
4392             for (int j = 0; j < N; j++) {
4393                 mAvailUidChanges.add(mActiveUidChanges[j]);
4394             }
4395         }
4396     }
4397
4398     private void dispatchUidsChangedForObserver(IUidObserver observer,
4399             UidObserverRegistration reg, int changesSize) {
4400         if (observer == null) {
4401             return;
4402         }
4403         try {
4404             for (int j = 0; j < changesSize; j++) {
4405                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4406                 final int change = item.change;
4407                 if (change == UidRecord.CHANGE_PROCSTATE &&
4408                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4409                     // No-op common case: no significant change, the observer is not
4410                     // interested in all proc state changes.
4411                     continue;
4412                 }
4413                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4414                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4415                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4416                                 "UID idle uid=" + item.uid);
4417                         observer.onUidIdle(item.uid, item.ephemeral);
4418                     }
4419                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4420                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4421                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                 "UID active uid=" + item.uid);
4423                         observer.onUidActive(item.uid);
4424                     }
4425                 }
4426                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4427                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
4428                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4429                                 "UID cached uid=" + item.uid);
4430                         observer.onUidCachedChanged(item.uid, true);
4431                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4432                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4433                                 "UID active uid=" + item.uid);
4434                         observer.onUidCachedChanged(item.uid, false);
4435                     }
4436                 }
4437                 if ((change & UidRecord.CHANGE_GONE) != 0) {
4438                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4439                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4440                                 "UID gone uid=" + item.uid);
4441                         observer.onUidGone(item.uid, item.ephemeral);
4442                     }
4443                     if (reg.lastProcStates != null) {
4444                         reg.lastProcStates.delete(item.uid);
4445                     }
4446                 } else {
4447                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4448                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4449                                 "UID CHANGED uid=" + item.uid
4450                                         + ": " + item.processState);
4451                         boolean doReport = true;
4452                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4453                             final int lastState = reg.lastProcStates.get(item.uid,
4454                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4455                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4456                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4457                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4458                                 doReport = lastAboveCut != newAboveCut;
4459                             } else {
4460                                 doReport = item.processState
4461                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4462                             }
4463                         }
4464                         if (doReport) {
4465                             if (reg.lastProcStates != null) {
4466                                 reg.lastProcStates.put(item.uid, item.processState);
4467                             }
4468                             observer.onUidStateChanged(item.uid, item.processState,
4469                                     item.procStateSeq);
4470                         }
4471                     }
4472                 }
4473             }
4474         } catch (RemoteException e) {
4475         }
4476     }
4477
4478     void dispatchOomAdjObserver(String msg) {
4479         OomAdjObserver observer;
4480         synchronized (this) {
4481             observer = mCurOomAdjObserver;
4482         }
4483
4484         if (observer != null) {
4485             observer.onOomAdjMessage(msg);
4486         }
4487     }
4488
4489     void setOomAdjObserver(int uid, OomAdjObserver observer) {
4490         synchronized (this) {
4491             mCurOomAdjUid = uid;
4492             mCurOomAdjObserver = observer;
4493         }
4494     }
4495
4496     void clearOomAdjObserver() {
4497         synchronized (this) {
4498             mCurOomAdjUid = -1;
4499             mCurOomAdjObserver = null;
4500         }
4501     }
4502
4503     void reportOomAdjMessageLocked(String tag, String msg) {
4504         Slog.d(tag, msg);
4505         if (mCurOomAdjObserver != null) {
4506             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4507         }
4508     }
4509
4510     @Override
4511     public final int startActivity(IApplicationThread caller, String callingPackage,
4512             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4513             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4514         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4515                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4516                 UserHandle.getCallingUserId());
4517     }
4518
4519     @Override
4520     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4521             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4522             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4523         enforceNotIsolatedCaller("startActivity");
4524         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4525                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4526         // TODO: Switch to user app stacks here.
4527         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4528                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4529                 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4530     }
4531
4532     @Override
4533     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4534             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4535             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4536             int userId) {
4537
4538         // This is very dangerous -- it allows you to perform a start activity (including
4539         // permission grants) as any app that may launch one of your own activities.  So
4540         // we will only allow this to be done from activities that are part of the core framework,
4541         // and then only when they are running as the system.
4542         final ActivityRecord sourceRecord;
4543         final int targetUid;
4544         final String targetPackage;
4545         synchronized (this) {
4546             if (resultTo == null) {
4547                 throw new SecurityException("Must be called from an activity");
4548             }
4549             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4550             if (sourceRecord == null) {
4551                 throw new SecurityException("Called with bad activity token: " + resultTo);
4552             }
4553             if (!sourceRecord.info.packageName.equals("android")) {
4554                 throw new SecurityException(
4555                         "Must be called from an activity that is declared in the android package");
4556             }
4557             if (sourceRecord.app == null) {
4558                 throw new SecurityException("Called without a process attached to activity");
4559             }
4560             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4561                 // This is still okay, as long as this activity is running under the
4562                 // uid of the original calling activity.
4563                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4564                     throw new SecurityException(
4565                             "Calling activity in uid " + sourceRecord.app.uid
4566                                     + " must be system uid or original calling uid "
4567                                     + sourceRecord.launchedFromUid);
4568                 }
4569             }
4570             if (ignoreTargetSecurity) {
4571                 if (intent.getComponent() == null) {
4572                     throw new SecurityException(
4573                             "Component must be specified with ignoreTargetSecurity");
4574                 }
4575                 if (intent.getSelector() != null) {
4576                     throw new SecurityException(
4577                             "Selector not allowed with ignoreTargetSecurity");
4578                 }
4579             }
4580             targetUid = sourceRecord.launchedFromUid;
4581             targetPackage = sourceRecord.launchedFromPackage;
4582         }
4583
4584         if (userId == UserHandle.USER_NULL) {
4585             userId = UserHandle.getUserId(sourceRecord.app.uid);
4586         }
4587
4588         // TODO: Switch to user app stacks here.
4589         try {
4590             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4591                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4592                     null, null, bOptions, ignoreTargetSecurity, userId, null,
4593                     "startActivityAsCaller");
4594             return ret;
4595         } catch (SecurityException e) {
4596             // XXX need to figure out how to propagate to original app.
4597             // A SecurityException here is generally actually a fault of the original
4598             // calling activity (such as a fairly granting permissions), so propagate it
4599             // back to them.
4600             /*
4601             StringBuilder msg = new StringBuilder();
4602             msg.append("While launching");
4603             msg.append(intent.toString());
4604             msg.append(": ");
4605             msg.append(e.getMessage());
4606             */
4607             throw e;
4608         }
4609     }
4610
4611     @Override
4612     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4613             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4614             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4615         enforceNotIsolatedCaller("startActivityAndWait");
4616         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4617                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4618         WaitResult res = new WaitResult();
4619         // TODO: Switch to user app stacks here.
4620         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4621                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4622                 bOptions, false, userId, null, "startActivityAndWait");
4623         return res;
4624     }
4625
4626     @Override
4627     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4628             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4629             int startFlags, Configuration config, Bundle bOptions, int userId) {
4630         enforceNotIsolatedCaller("startActivityWithConfig");
4631         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4632                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4633         // TODO: Switch to user app stacks here.
4634         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4635                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4636                 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4637         return ret;
4638     }
4639
4640     @Override
4641     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4642             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4643             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4644             throws TransactionTooLargeException {
4645         enforceNotIsolatedCaller("startActivityIntentSender");
4646         // Refuse possible leaked file descriptors
4647         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4648             throw new IllegalArgumentException("File descriptors passed in Intent");
4649         }
4650
4651         if (!(target instanceof PendingIntentRecord)) {
4652             throw new IllegalArgumentException("Bad PendingIntent object");
4653         }
4654
4655         PendingIntentRecord pir = (PendingIntentRecord)target;
4656
4657         synchronized (this) {
4658             // If this is coming from the currently resumed activity, it is
4659             // effectively saying that app switches are allowed at this point.
4660             final ActivityStack stack = getFocusedStack();
4661             if (stack.mResumedActivity != null &&
4662                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4663                 mAppSwitchesAllowedTime = 0;
4664             }
4665         }
4666         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4667                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4668         return ret;
4669     }
4670
4671     @Override
4672     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4673             Intent intent, String resolvedType, IVoiceInteractionSession session,
4674             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4675             Bundle bOptions, int userId) {
4676         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4677                 != PackageManager.PERMISSION_GRANTED) {
4678             String msg = "Permission Denial: startVoiceActivity() from pid="
4679                     + Binder.getCallingPid()
4680                     + ", uid=" + Binder.getCallingUid()
4681                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4682             Slog.w(TAG, msg);
4683             throw new SecurityException(msg);
4684         }
4685         if (session == null || interactor == null) {
4686             throw new NullPointerException("null session or interactor");
4687         }
4688         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4689                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4690         // TODO: Switch to user app stacks here.
4691         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4692                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4693                 null, bOptions, false, userId, null, "startVoiceActivity");
4694     }
4695
4696     @Override
4697     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4698             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4699         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4700                 != PackageManager.PERMISSION_GRANTED) {
4701             final String msg = "Permission Denial: startAssistantActivity() from pid="
4702                     + Binder.getCallingPid()
4703                     + ", uid=" + Binder.getCallingUid()
4704                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4705             Slog.w(TAG, msg);
4706             throw new SecurityException(msg);
4707         }
4708         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4709                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4710         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4711                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4712                 userId, null, "startAssistantActivity");
4713     }
4714
4715     @Override
4716     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4717             throws RemoteException {
4718         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4719         synchronized (this) {
4720             ActivityRecord activity = getFocusedStack().topActivity();
4721             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4722                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4723             }
4724             if (mRunningVoice != null || activity.getTask().voiceSession != null
4725                     || activity.voiceSession != null) {
4726                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4727                 return;
4728             }
4729             if (activity.pendingVoiceInteractionStart) {
4730                 Slog.w(TAG, "Pending start of voice interaction already.");
4731                 return;
4732             }
4733             activity.pendingVoiceInteractionStart = true;
4734         }
4735         LocalServices.getService(VoiceInteractionManagerInternal.class)
4736                 .startLocalVoiceInteraction(callingActivity, options);
4737     }
4738
4739     @Override
4740     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4741         LocalServices.getService(VoiceInteractionManagerInternal.class)
4742                 .stopLocalVoiceInteraction(callingActivity);
4743     }
4744
4745     @Override
4746     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4747         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4748                 .supportsLocalVoiceInteraction();
4749     }
4750
4751     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4752             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4753         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4754         if (activityToCallback == null) return;
4755         activityToCallback.setVoiceSessionLocked(voiceSession);
4756
4757         // Inform the activity
4758         try {
4759             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4760                     voiceInteractor);
4761             long token = Binder.clearCallingIdentity();
4762             try {
4763                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4764             } finally {
4765                 Binder.restoreCallingIdentity(token);
4766             }
4767             // TODO: VI Should we cache the activity so that it's easier to find later
4768             // rather than scan through all the stacks and activities?
4769         } catch (RemoteException re) {
4770             activityToCallback.clearVoiceSessionLocked();
4771             // TODO: VI Should this terminate the voice session?
4772         }
4773     }
4774
4775     @Override
4776     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4777         synchronized (this) {
4778             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4779                 if (keepAwake) {
4780                     mVoiceWakeLock.acquire();
4781                 } else {
4782                     mVoiceWakeLock.release();
4783                 }
4784             }
4785         }
4786     }
4787
4788     @Override
4789     public boolean startNextMatchingActivity(IBinder callingActivity,
4790             Intent intent, Bundle bOptions) {
4791         // Refuse possible leaked file descriptors
4792         if (intent != null && intent.hasFileDescriptors() == true) {
4793             throw new IllegalArgumentException("File descriptors passed in Intent");
4794         }
4795         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4796
4797         synchronized (this) {
4798             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4799             if (r == null) {
4800                 ActivityOptions.abort(options);
4801                 return false;
4802             }
4803             if (r.app == null || r.app.thread == null) {
4804                 // The caller is not running...  d'oh!
4805                 ActivityOptions.abort(options);
4806                 return false;
4807             }
4808             intent = new Intent(intent);
4809             // The caller is not allowed to change the data.
4810             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4811             // And we are resetting to find the next component...
4812             intent.setComponent(null);
4813
4814             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4815
4816             ActivityInfo aInfo = null;
4817             try {
4818                 List<ResolveInfo> resolves =
4819                     AppGlobals.getPackageManager().queryIntentActivities(
4820                             intent, r.resolvedType,
4821                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4822                             UserHandle.getCallingUserId()).getList();
4823
4824                 // Look for the original activity in the list...
4825                 final int N = resolves != null ? resolves.size() : 0;
4826                 for (int i=0; i<N; i++) {
4827                     ResolveInfo rInfo = resolves.get(i);
4828                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4829                             && rInfo.activityInfo.name.equals(r.info.name)) {
4830                         // We found the current one...  the next matching is
4831                         // after it.
4832                         i++;
4833                         if (i<N) {
4834                             aInfo = resolves.get(i).activityInfo;
4835                         }
4836                         if (debug) {
4837                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4838                                     + "/" + r.info.name);
4839                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4840                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4841                         }
4842                         break;
4843                     }
4844                 }
4845             } catch (RemoteException e) {
4846             }
4847
4848             if (aInfo == null) {
4849                 // Nobody who is next!
4850                 ActivityOptions.abort(options);
4851                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4852                 return false;
4853             }
4854
4855             intent.setComponent(new ComponentName(
4856                     aInfo.applicationInfo.packageName, aInfo.name));
4857             intent.setFlags(intent.getFlags()&~(
4858                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4859                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4860                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4861                     Intent.FLAG_ACTIVITY_NEW_TASK));
4862
4863             // Okay now we need to start the new activity, replacing the
4864             // currently running activity.  This is a little tricky because
4865             // we want to start the new one as if the current one is finished,
4866             // but not finish the current one first so that there is no flicker.
4867             // And thus...
4868             final boolean wasFinishing = r.finishing;
4869             r.finishing = true;
4870
4871             // Propagate reply information over to the new activity.
4872             final ActivityRecord resultTo = r.resultTo;
4873             final String resultWho = r.resultWho;
4874             final int requestCode = r.requestCode;
4875             r.resultTo = null;
4876             if (resultTo != null) {
4877                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4878             }
4879
4880             final long origId = Binder.clearCallingIdentity();
4881             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4882                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4883                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4884                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4885                     false, false, null, null, "startNextMatchingActivity");
4886             Binder.restoreCallingIdentity(origId);
4887
4888             r.finishing = wasFinishing;
4889             if (res != ActivityManager.START_SUCCESS) {
4890                 return false;
4891             }
4892             return true;
4893         }
4894     }
4895
4896     @Override
4897     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4898         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4899             String msg = "Permission Denial: startActivityFromRecents called without " +
4900                     START_TASKS_FROM_RECENTS;
4901             Slog.w(TAG, msg);
4902             throw new SecurityException(msg);
4903         }
4904         final long origId = Binder.clearCallingIdentity();
4905         try {
4906             synchronized (this) {
4907                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4908             }
4909         } finally {
4910             Binder.restoreCallingIdentity(origId);
4911         }
4912     }
4913
4914     final int startActivityInPackage(int uid, String callingPackage,
4915             Intent intent, String resolvedType, IBinder resultTo,
4916             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4917             TaskRecord inTask, String reason) {
4918
4919         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4920                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4921
4922         // TODO: Switch to user app stacks here.
4923         return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4924                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4925                 null, null, null, bOptions, false, userId, inTask, reason);
4926     }
4927
4928     @Override
4929     public final int startActivities(IApplicationThread caller, String callingPackage,
4930             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4931             int userId) {
4932         final String reason = "startActivities";
4933         enforceNotIsolatedCaller(reason);
4934         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4935                 userId, false, ALLOW_FULL_ONLY, reason, null);
4936         // TODO: Switch to user app stacks here.
4937         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4938                 resolvedTypes, resultTo, bOptions, userId, reason);
4939         return ret;
4940     }
4941
4942     final int startActivitiesInPackage(int uid, String callingPackage,
4943             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4944             Bundle bOptions, int userId) {
4945
4946         final String reason = "startActivityInPackage";
4947         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4948                 userId, false, ALLOW_FULL_ONLY, reason, null);
4949         // TODO: Switch to user app stacks here.
4950         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4951                 resultTo, bOptions, userId, reason);
4952         return ret;
4953     }
4954
4955     @Override
4956     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4957         synchronized (this) {
4958             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4959             if (r == null) {
4960                 return;
4961             }
4962             r.reportFullyDrawnLocked(restoredFromBundle);
4963         }
4964     }
4965
4966     @Override
4967     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4968         synchronized (this) {
4969             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4970             if (r == null) {
4971                 return;
4972             }
4973             final long origId = Binder.clearCallingIdentity();
4974             try {
4975                 r.setRequestedOrientation(requestedOrientation);
4976             } finally {
4977                 Binder.restoreCallingIdentity(origId);
4978             }
4979         }
4980     }
4981
4982     @Override
4983     public int getRequestedOrientation(IBinder token) {
4984         synchronized (this) {
4985             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4986             if (r == null) {
4987                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4988             }
4989             return r.getRequestedOrientation();
4990         }
4991     }
4992
4993     @Override
4994     public final void requestActivityRelaunch(IBinder token) {
4995         synchronized(this) {
4996             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4997             if (r == null) {
4998                 return;
4999             }
5000             final long origId = Binder.clearCallingIdentity();
5001             try {
5002                 r.forceNewConfig = true;
5003                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5004                         true /* preserveWindow */);
5005             } finally {
5006                 Binder.restoreCallingIdentity(origId);
5007             }
5008         }
5009     }
5010
5011     /**
5012      * This is the internal entry point for handling Activity.finish().
5013      *
5014      * @param token The Binder token referencing the Activity we want to finish.
5015      * @param resultCode Result code, if any, from this Activity.
5016      * @param resultData Result data (Intent), if any, from this Activity.
5017      * @param finishTask Whether to finish the task associated with this Activity.
5018      *
5019      * @return Returns true if the activity successfully finished, or false if it is still running.
5020      */
5021     @Override
5022     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5023             int finishTask) {
5024         // Refuse possible leaked file descriptors
5025         if (resultData != null && resultData.hasFileDescriptors() == true) {
5026             throw new IllegalArgumentException("File descriptors passed in Intent");
5027         }
5028
5029         synchronized(this) {
5030             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5031             if (r == null) {
5032                 return true;
5033             }
5034             // Keep track of the root activity of the task before we finish it
5035             TaskRecord tr = r.getTask();
5036             ActivityRecord rootR = tr.getRootActivity();
5037             if (rootR == null) {
5038                 Slog.w(TAG, "Finishing task with all activities already finished");
5039             }
5040             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5041             // finish.
5042             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5043                     mStackSupervisor.isLastLockedTask(tr)) {
5044                 Slog.i(TAG, "Not finishing task in lock task mode");
5045                 mStackSupervisor.showLockTaskToast();
5046                 return false;
5047             }
5048             if (mController != null) {
5049                 // Find the first activity that is not finishing.
5050                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5051                 if (next != null) {
5052                     // ask watcher if this is allowed
5053                     boolean resumeOK = true;
5054                     try {
5055                         resumeOK = mController.activityResuming(next.packageName);
5056                     } catch (RemoteException e) {
5057                         mController = null;
5058                         Watchdog.getInstance().setActivityController(null);
5059                     }
5060
5061                     if (!resumeOK) {
5062                         Slog.i(TAG, "Not finishing activity because controller resumed");
5063                         return false;
5064                     }
5065                 }
5066             }
5067             final long origId = Binder.clearCallingIdentity();
5068             try {
5069                 boolean res;
5070                 final boolean finishWithRootActivity =
5071                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5072                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5073                         || (finishWithRootActivity && r == rootR)) {
5074                     // If requested, remove the task that is associated to this activity only if it
5075                     // was the root activity in the task. The result code and data is ignored
5076                     // because we don't support returning them across task boundaries. Also, to
5077                     // keep backwards compatibility we remove the task from recents when finishing
5078                     // task with root activity.
5079                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5080                     if (!res) {
5081                         Slog.i(TAG, "Removing task failed to finish activity");
5082                     }
5083                 } else {
5084                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5085                             resultData, "app-request", true);
5086                     if (!res) {
5087                         Slog.i(TAG, "Failed to finish by app-request");
5088                     }
5089                 }
5090                 return res;
5091             } finally {
5092                 Binder.restoreCallingIdentity(origId);
5093             }
5094         }
5095     }
5096
5097     @Override
5098     public final void finishHeavyWeightApp() {
5099         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5100                 != PackageManager.PERMISSION_GRANTED) {
5101             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5102                     + Binder.getCallingPid()
5103                     + ", uid=" + Binder.getCallingUid()
5104                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5105             Slog.w(TAG, msg);
5106             throw new SecurityException(msg);
5107         }
5108
5109         synchronized(this) {
5110             if (mHeavyWeightProcess == null) {
5111                 return;
5112             }
5113
5114             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5115             for (int i = 0; i < activities.size(); i++) {
5116                 ActivityRecord r = activities.get(i);
5117                 if (!r.finishing && r.isInStackLocked()) {
5118                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5119                             null, "finish-heavy", true);
5120                 }
5121             }
5122
5123             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5124                     mHeavyWeightProcess.userId, 0));
5125             mHeavyWeightProcess = null;
5126         }
5127     }
5128
5129     @Override
5130     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5131             String message) {
5132         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5133                 != PackageManager.PERMISSION_GRANTED) {
5134             String msg = "Permission Denial: crashApplication() from pid="
5135                     + Binder.getCallingPid()
5136                     + ", uid=" + Binder.getCallingUid()
5137                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5138             Slog.w(TAG, msg);
5139             throw new SecurityException(msg);
5140         }
5141
5142         synchronized(this) {
5143             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5144         }
5145     }
5146
5147     @Override
5148     public final void finishSubActivity(IBinder token, String resultWho,
5149             int requestCode) {
5150         synchronized(this) {
5151             final long origId = Binder.clearCallingIdentity();
5152             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5153             if (r != null) {
5154                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5155             }
5156             Binder.restoreCallingIdentity(origId);
5157         }
5158     }
5159
5160     @Override
5161     public boolean finishActivityAffinity(IBinder token) {
5162         synchronized(this) {
5163             final long origId = Binder.clearCallingIdentity();
5164             try {
5165                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5166                 if (r == null) {
5167                     return false;
5168                 }
5169
5170                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5171                 // can finish.
5172                 final TaskRecord task = r.getTask();
5173                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5174                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5175                     mStackSupervisor.showLockTaskToast();
5176                     return false;
5177                 }
5178                 return task.getStack().finishActivityAffinityLocked(r);
5179             } finally {
5180                 Binder.restoreCallingIdentity(origId);
5181             }
5182         }
5183     }
5184
5185     @Override
5186     public void finishVoiceTask(IVoiceInteractionSession session) {
5187         synchronized (this) {
5188             final long origId = Binder.clearCallingIdentity();
5189             try {
5190                 // TODO: VI Consider treating local voice interactions and voice tasks
5191                 // differently here
5192                 mStackSupervisor.finishVoiceTask(session);
5193             } finally {
5194                 Binder.restoreCallingIdentity(origId);
5195             }
5196         }
5197
5198     }
5199
5200     @Override
5201     public boolean releaseActivityInstance(IBinder token) {
5202         synchronized(this) {
5203             final long origId = Binder.clearCallingIdentity();
5204             try {
5205                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5206                 if (r == null) {
5207                     return false;
5208                 }
5209                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5210             } finally {
5211                 Binder.restoreCallingIdentity(origId);
5212             }
5213         }
5214     }
5215
5216     @Override
5217     public void releaseSomeActivities(IApplicationThread appInt) {
5218         synchronized(this) {
5219             final long origId = Binder.clearCallingIdentity();
5220             try {
5221                 ProcessRecord app = getRecordForAppLocked(appInt);
5222                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5223             } finally {
5224                 Binder.restoreCallingIdentity(origId);
5225             }
5226         }
5227     }
5228
5229     @Override
5230     public boolean willActivityBeVisible(IBinder token) {
5231         synchronized(this) {
5232             ActivityStack stack = ActivityRecord.getStackLocked(token);
5233             if (stack != null) {
5234                 return stack.willActivityBeVisibleLocked(token);
5235             }
5236             return false;
5237         }
5238     }
5239
5240     @Override
5241     public void overridePendingTransition(IBinder token, String packageName,
5242             int enterAnim, int exitAnim) {
5243         synchronized(this) {
5244             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5245             if (self == null) {
5246                 return;
5247             }
5248
5249             final long origId = Binder.clearCallingIdentity();
5250
5251             if (self.state == ActivityState.RESUMED
5252                     || self.state == ActivityState.PAUSING) {
5253                 mWindowManager.overridePendingAppTransition(packageName,
5254                         enterAnim, exitAnim, null);
5255             }
5256
5257             Binder.restoreCallingIdentity(origId);
5258         }
5259     }
5260
5261     /**
5262      * Main function for removing an existing process from the activity manager
5263      * as a result of that process going away.  Clears out all connections
5264      * to the process.
5265      */
5266     private final void handleAppDiedLocked(ProcessRecord app,
5267             boolean restarting, boolean allowRestart) {
5268         int pid = app.pid;
5269         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5270                 false /*replacingPid*/);
5271         if (!kept && !restarting) {
5272             removeLruProcessLocked(app);
5273             if (pid > 0) {
5274                 ProcessList.remove(pid);
5275             }
5276         }
5277
5278         if (mProfileProc == app) {
5279             clearProfilerLocked();
5280         }
5281
5282         // Remove this application's activities from active lists.
5283         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5284
5285         app.activities.clear();
5286
5287         if (app.instr != null) {
5288             Slog.w(TAG, "Crash of app " + app.processName
5289                   + " running instrumentation " + app.instr.mClass);
5290             Bundle info = new Bundle();
5291             info.putString("shortMsg", "Process crashed.");
5292             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5293         }
5294
5295         mWindowManager.deferSurfaceLayout();
5296         try {
5297             if (!restarting && hasVisibleActivities
5298                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5299                 // If there was nothing to resume, and we are not already restarting this process, but
5300                 // there is a visible activity that is hosted by the process...  then make sure all
5301                 // visible activities are running, taking care of restarting this process.
5302                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5303             }
5304         } finally {
5305             mWindowManager.continueSurfaceLayout();
5306         }
5307     }
5308
5309     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5310         final IBinder threadBinder = thread.asBinder();
5311         // Find the application record.
5312         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5313             final ProcessRecord rec = mLruProcesses.get(i);
5314             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5315                 return i;
5316             }
5317         }
5318         return -1;
5319     }
5320
5321     final ProcessRecord getRecordForAppLocked(
5322             IApplicationThread thread) {
5323         if (thread == null) {
5324             return null;
5325         }
5326
5327         int appIndex = getLRURecordIndexForAppLocked(thread);
5328         if (appIndex >= 0) {
5329             return mLruProcesses.get(appIndex);
5330         }
5331
5332         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5333         // double-check that.
5334         final IBinder threadBinder = thread.asBinder();
5335         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5336         for (int i = pmap.size()-1; i >= 0; i--) {
5337             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5338             for (int j = procs.size()-1; j >= 0; j--) {
5339                 final ProcessRecord proc = procs.valueAt(j);
5340                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5341                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5342                             + proc);
5343                     return proc;
5344                 }
5345             }
5346         }
5347
5348         return null;
5349     }
5350
5351     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5352         // If there are no longer any background processes running,
5353         // and the app that died was not running instrumentation,
5354         // then tell everyone we are now low on memory.
5355         boolean haveBg = false;
5356         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5357             ProcessRecord rec = mLruProcesses.get(i);
5358             if (rec.thread != null
5359                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5360                 haveBg = true;
5361                 break;
5362             }
5363         }
5364
5365         if (!haveBg) {
5366             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5367             if (doReport) {
5368                 long now = SystemClock.uptimeMillis();
5369                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5370                     doReport = false;
5371                 } else {
5372                     mLastMemUsageReportTime = now;
5373                 }
5374             }
5375             final ArrayList<ProcessMemInfo> memInfos
5376                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5377             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5378             long now = SystemClock.uptimeMillis();
5379             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5380                 ProcessRecord rec = mLruProcesses.get(i);
5381                 if (rec == dyingProc || rec.thread == null) {
5382                     continue;
5383                 }
5384                 if (doReport) {
5385                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5386                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5387                 }
5388                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5389                     // The low memory report is overriding any current
5390                     // state for a GC request.  Make sure to do
5391                     // heavy/important/visible/foreground processes first.
5392                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5393                         rec.lastRequestedGc = 0;
5394                     } else {
5395                         rec.lastRequestedGc = rec.lastLowMemory;
5396                     }
5397                     rec.reportLowMemory = true;
5398                     rec.lastLowMemory = now;
5399                     mProcessesToGc.remove(rec);
5400                     addProcessToGcListLocked(rec);
5401                 }
5402             }
5403             if (doReport) {
5404                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5405                 mHandler.sendMessage(msg);
5406             }
5407             scheduleAppGcsLocked();
5408         }
5409     }
5410
5411     final void appDiedLocked(ProcessRecord app) {
5412        appDiedLocked(app, app.pid, app.thread, false);
5413     }
5414
5415     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5416             boolean fromBinderDied) {
5417         // First check if this ProcessRecord is actually active for the pid.
5418         synchronized (mPidsSelfLocked) {
5419             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5420             if (curProc != app) {
5421                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5422                 return;
5423             }
5424         }
5425
5426         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5427         synchronized (stats) {
5428             stats.noteProcessDiedLocked(app.info.uid, pid);
5429         }
5430
5431         if (!app.killed) {
5432             if (!fromBinderDied) {
5433                 killProcessQuiet(pid);
5434             }
5435             killProcessGroup(app.uid, pid);
5436             app.killed = true;
5437         }
5438
5439         // Clean up already done if the process has been re-started.
5440         if (app.pid == pid && app.thread != null &&
5441                 app.thread.asBinder() == thread.asBinder()) {
5442             boolean doLowMem = app.instr == null;
5443             boolean doOomAdj = doLowMem;
5444             if (!app.killedByAm) {
5445                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5446                         + ProcessList.makeOomAdjString(app.setAdj)
5447                         + ProcessList.makeProcStateString(app.setProcState));
5448                 mAllowLowerMemLevel = true;
5449             } else {
5450                 // Note that we always want to do oom adj to update our state with the
5451                 // new number of procs.
5452                 mAllowLowerMemLevel = false;
5453                 doLowMem = false;
5454             }
5455             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5456                     app.setAdj, app.setProcState);
5457             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5458                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5459             handleAppDiedLocked(app, false, true);
5460
5461             if (doOomAdj) {
5462                 updateOomAdjLocked();
5463             }
5464             if (doLowMem) {
5465                 doLowMemReportIfNeededLocked(app);
5466             }
5467         } else if (app.pid != pid) {
5468             // A new process has already been started.
5469             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5470                     + ") has died and restarted (pid " + app.pid + ").");
5471             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5472         } else if (DEBUG_PROCESSES) {
5473             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5474                     + thread.asBinder());
5475         }
5476     }
5477
5478     /**
5479      * If a stack trace dump file is configured, dump process stack traces.
5480      * @param clearTraces causes the dump file to be erased prior to the new
5481      *    traces being written, if true; when false, the new traces will be
5482      *    appended to any existing file content.
5483      * @param firstPids of dalvik VM processes to dump stack traces for first
5484      * @param lastPids of dalvik VM processes to dump stack traces for last
5485      * @param nativePids optional list of native pids to dump stack crawls
5486      */
5487     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5488             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5489             ArrayList<Integer> nativePids) {
5490         ArrayList<Integer> extraPids = null;
5491
5492         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5493         // of the top users at the time of the request.
5494         if (processCpuTracker != null) {
5495             processCpuTracker.init();
5496             try {
5497                 Thread.sleep(200);
5498             } catch (InterruptedException ignored) {
5499             }
5500
5501             processCpuTracker.update();
5502
5503             // We'll take the stack crawls of just the top apps using CPU.
5504             final int N = processCpuTracker.countWorkingStats();
5505             extraPids = new ArrayList<>();
5506             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5507                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5508                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5509                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5510
5511                     extraPids.add(stats.pid);
5512                 } else if (DEBUG_ANR) {
5513                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5514                             + stats.pid);
5515                 }
5516             }
5517         }
5518
5519         boolean useTombstonedForJavaTraces = false;
5520         File tracesFile;
5521
5522         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5523         if (tracesDirProp.isEmpty()) {
5524             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5525             // dumping scheme. All traces are written to a global trace file (usually
5526             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5527             // the file if requested.
5528             //
5529             // This mode of operation will be removed in the near future.
5530
5531
5532             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5533             if (globalTracesPath.isEmpty()) {
5534                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5535                 return null;
5536             }
5537
5538             tracesFile = new File(globalTracesPath);
5539             try {
5540                 if (clearTraces && tracesFile.exists()) {
5541                     tracesFile.delete();
5542                 }
5543
5544                 tracesFile.createNewFile();
5545                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5546             } catch (IOException e) {
5547                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5548                 return null;
5549             }
5550         } else {
5551             File tracesDir = new File(tracesDirProp);
5552             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5553             // Each set of ANR traces is written to a separate file and dumpstate will process
5554             // all such files and add them to a captured bug report if they're recent enough.
5555             maybePruneOldTraces(tracesDir);
5556
5557             // NOTE: We should consider creating the file in native code atomically once we've
5558             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5559             // can be removed.
5560             tracesFile = createAnrDumpFile(tracesDir);
5561             if (tracesFile == null) {
5562                 return null;
5563             }
5564
5565             useTombstonedForJavaTraces = true;
5566         }
5567
5568         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5569                 useTombstonedForJavaTraces);
5570         return tracesFile;
5571     }
5572
5573     @GuardedBy("ActivityManagerService.class")
5574     private static SimpleDateFormat sAnrFileDateFormat;
5575
5576     private static synchronized File createAnrDumpFile(File tracesDir) {
5577         if (sAnrFileDateFormat == null) {
5578             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5579         }
5580
5581         final String formattedDate = sAnrFileDateFormat.format(new Date());
5582         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5583
5584         try {
5585             if (anrFile.createNewFile()) {
5586                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5587                 return anrFile;
5588             } else {
5589                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5590             }
5591         } catch (IOException ioe) {
5592             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5593         }
5594
5595         return null;
5596     }
5597
5598     /**
5599      * Prune all trace files that are more than a day old.
5600      *
5601      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5602      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5603      * since it's the system_server that creates trace files for most ANRs.
5604      */
5605     private static void maybePruneOldTraces(File tracesDir) {
5606         final long now = System.currentTimeMillis();
5607         final File[] traceFiles = tracesDir.listFiles();
5608
5609         if (traceFiles != null) {
5610             for (File file : traceFiles) {
5611                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5612                     if (!file.delete()) {
5613                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
5614                     }
5615                 }
5616             }
5617         }
5618     }
5619
5620     /**
5621      * Legacy code, do not use. Existing users will be deleted.
5622      *
5623      * @deprecated
5624      */
5625     @Deprecated
5626     public static class DumpStackFileObserver extends FileObserver {
5627         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5628         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5629
5630         private final String mTracesPath;
5631         private boolean mClosed;
5632
5633         public DumpStackFileObserver(String tracesPath) {
5634             super(tracesPath, FileObserver.CLOSE_WRITE);
5635             mTracesPath = tracesPath;
5636         }
5637
5638         @Override
5639         public synchronized void onEvent(int event, String path) {
5640             mClosed = true;
5641             notify();
5642         }
5643
5644         public long dumpWithTimeout(int pid, long timeout) {
5645             sendSignal(pid, SIGNAL_QUIT);
5646             final long start = SystemClock.elapsedRealtime();
5647
5648             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5649             synchronized (this) {
5650                 try {
5651                     wait(waitTime); // Wait for traces file to be closed.
5652                 } catch (InterruptedException e) {
5653                     Slog.wtf(TAG, e);
5654                 }
5655             }
5656
5657             // This avoids a corner case of passing a negative time to the native
5658             // trace in case we've already hit the overall timeout.
5659             final long timeWaited = SystemClock.elapsedRealtime() - start;
5660             if (timeWaited >= timeout) {
5661                 return timeWaited;
5662             }
5663
5664             if (!mClosed) {
5665                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5666                        ". Attempting native stack collection.");
5667
5668                 final long nativeDumpTimeoutMs = Math.min(
5669                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5670
5671                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5672                         (int) (nativeDumpTimeoutMs / 1000));
5673             }
5674
5675             final long end = SystemClock.elapsedRealtime();
5676             mClosed = false;
5677
5678             return (end - start);
5679         }
5680     }
5681
5682     /**
5683      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5684      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5685      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5686      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5687      * capturing traces.
5688      */
5689     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5690         final long timeStart = SystemClock.elapsedRealtime();
5691         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5692             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5693                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5694         }
5695
5696         return SystemClock.elapsedRealtime() - timeStart;
5697     }
5698
5699     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5700             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5701             boolean useTombstonedForJavaTraces) {
5702
5703         // We don't need any sort of inotify based monitoring when we're dumping traces via
5704         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5705         // control of all writes to the file in question.
5706         final DumpStackFileObserver observer;
5707         if (useTombstonedForJavaTraces) {
5708             observer = null;
5709         } else {
5710             // Use a FileObserver to detect when traces finish writing.
5711             // The order of traces is considered important to maintain for legibility.
5712             observer = new DumpStackFileObserver(tracesFile);
5713         }
5714
5715         // We must complete all stack dumps within 20 seconds.
5716         long remainingTime = 20 * 1000;
5717         try {
5718             if (observer != null) {
5719                 observer.startWatching();
5720             }
5721
5722             // First collect all of the stacks of the most important pids.
5723             if (firstPids != null) {
5724                 int num = firstPids.size();
5725                 for (int i = 0; i < num; i++) {
5726                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5727                             + firstPids.get(i));
5728                     final long timeTaken;
5729                     if (useTombstonedForJavaTraces) {
5730                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5731                     } else {
5732                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5733                     }
5734
5735                     remainingTime -= timeTaken;
5736                     if (remainingTime <= 0) {
5737                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5738                             "); deadline exceeded.");
5739                         return;
5740                     }
5741
5742                     if (DEBUG_ANR) {
5743                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5744                     }
5745                 }
5746             }
5747
5748             // Next collect the stacks of the native pids
5749             if (nativePids != null) {
5750                 for (int pid : nativePids) {
5751                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5752                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5753
5754                     final long start = SystemClock.elapsedRealtime();
5755                     Debug.dumpNativeBacktraceToFileTimeout(
5756                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5757                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5758
5759                     remainingTime -= timeTaken;
5760                     if (remainingTime <= 0) {
5761                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5762                             "); deadline exceeded.");
5763                         return;
5764                     }
5765
5766                     if (DEBUG_ANR) {
5767                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5768                     }
5769                 }
5770             }
5771
5772             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5773             if (extraPids != null) {
5774                 for (int pid : extraPids) {
5775                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5776
5777                     final long timeTaken;
5778                     if (useTombstonedForJavaTraces) {
5779                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5780                     } else {
5781                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5782                     }
5783
5784                     remainingTime -= timeTaken;
5785                     if (remainingTime <= 0) {
5786                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5787                                 "); deadline exceeded.");
5788                         return;
5789                     }
5790
5791                     if (DEBUG_ANR) {
5792                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5793                     }
5794                 }
5795             }
5796         } finally {
5797             if (observer != null) {
5798                 observer.stopWatching();
5799             }
5800         }
5801     }
5802
5803     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5804         if (true || Build.IS_USER) {
5805             return;
5806         }
5807         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5808         if (tracesPath == null || tracesPath.length() == 0) {
5809             return;
5810         }
5811
5812         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5813         StrictMode.allowThreadDiskWrites();
5814         try {
5815             final File tracesFile = new File(tracesPath);
5816             final File tracesDir = tracesFile.getParentFile();
5817             final File tracesTmp = new File(tracesDir, "__tmp__");
5818             try {
5819                 if (tracesFile.exists()) {
5820                     tracesTmp.delete();
5821                     tracesFile.renameTo(tracesTmp);
5822                 }
5823                 StringBuilder sb = new StringBuilder();
5824                 Time tobj = new Time();
5825                 tobj.set(System.currentTimeMillis());
5826                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5827                 sb.append(": ");
5828                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5829                 sb.append(" since ");
5830                 sb.append(msg);
5831                 FileOutputStream fos = new FileOutputStream(tracesFile);
5832                 fos.write(sb.toString().getBytes());
5833                 if (app == null) {
5834                     fos.write("\n*** No application process!".getBytes());
5835                 }
5836                 fos.close();
5837                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5838             } catch (IOException e) {
5839                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5840                 return;
5841             }
5842
5843             if (app != null) {
5844                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5845                 firstPids.add(app.pid);
5846                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5847             }
5848
5849             File lastTracesFile = null;
5850             File curTracesFile = null;
5851             for (int i=9; i>=0; i--) {
5852                 String name = String.format(Locale.US, "slow%02d.txt", i);
5853                 curTracesFile = new File(tracesDir, name);
5854                 if (curTracesFile.exists()) {
5855                     if (lastTracesFile != null) {
5856                         curTracesFile.renameTo(lastTracesFile);
5857                     } else {
5858                         curTracesFile.delete();
5859                     }
5860                 }
5861                 lastTracesFile = curTracesFile;
5862             }
5863             tracesFile.renameTo(curTracesFile);
5864             if (tracesTmp.exists()) {
5865                 tracesTmp.renameTo(tracesFile);
5866             }
5867         } finally {
5868             StrictMode.setThreadPolicy(oldPolicy);
5869         }
5870     }
5871
5872     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5873         if (!mLaunchWarningShown) {
5874             mLaunchWarningShown = true;
5875             mUiHandler.post(new Runnable() {
5876                 @Override
5877                 public void run() {
5878                     synchronized (ActivityManagerService.this) {
5879                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5880                         d.show();
5881                         mUiHandler.postDelayed(new Runnable() {
5882                             @Override
5883                             public void run() {
5884                                 synchronized (ActivityManagerService.this) {
5885                                     d.dismiss();
5886                                     mLaunchWarningShown = false;
5887                                 }
5888                             }
5889                         }, 4000);
5890                     }
5891                 }
5892             });
5893         }
5894     }
5895
5896     @Override
5897     public boolean clearApplicationUserData(final String packageName,
5898             final IPackageDataObserver observer, int userId) {
5899         enforceNotIsolatedCaller("clearApplicationUserData");
5900         int uid = Binder.getCallingUid();
5901         int pid = Binder.getCallingPid();
5902         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5903                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5904
5905         final ApplicationInfo appInfo;
5906         final boolean isInstantApp;
5907
5908         long callingId = Binder.clearCallingIdentity();
5909         try {
5910             IPackageManager pm = AppGlobals.getPackageManager();
5911             synchronized(this) {
5912                 // Instant packages are not protected
5913                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5914                         resolvedUserId, packageName)) {
5915                     throw new SecurityException(
5916                             "Cannot clear data for a protected package: " + packageName);
5917                 }
5918
5919                 ApplicationInfo applicationInfo = null;
5920                 try {
5921                     applicationInfo = pm.getApplicationInfo(packageName,
5922                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5923                 } catch (RemoteException e) {
5924                     /* ignore */
5925                 }
5926                 appInfo = applicationInfo;
5927
5928                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5929
5930                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5931                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5932                     throw new SecurityException("PID " + pid + " does not have permission "
5933                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5934                             + " of package " + packageName);
5935                 }
5936
5937                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5938                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
5939                 final boolean isUninstalledAppWithoutInstantMetadata =
5940                         (appInfo == null && !hasInstantMetadata);
5941                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5942                         || hasInstantMetadata;
5943                 final boolean canAccessInstantApps = checkComponentPermission(
5944                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5945                         == PackageManager.PERMISSION_GRANTED;
5946
5947                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5948                         && !canAccessInstantApps)) {
5949                     Slog.w(TAG, "Invalid packageName: " + packageName);
5950                     if (observer != null) {
5951                         try {
5952                             observer.onRemoveCompleted(packageName, false);
5953                         } catch (RemoteException e) {
5954                             Slog.i(TAG, "Observer no longer exists.");
5955                         }
5956                     }
5957                     return false;
5958                 }
5959
5960                 if (appInfo != null) {
5961                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5962                     // Remove all tasks match the cleared application package and user
5963                     for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5964                         final TaskRecord tr = mRecentTasks.get(i);
5965                         final String taskPackageName =
5966                                 tr.getBaseIntent().getComponent().getPackageName();
5967                         if (tr.userId != resolvedUserId) continue;
5968                         if (!taskPackageName.equals(packageName)) continue;
5969                         mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5970                                 REMOVE_FROM_RECENTS);
5971                     }
5972                 }
5973             }
5974
5975             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5976                 @Override
5977                 public void onRemoveCompleted(String packageName, boolean succeeded)
5978                         throws RemoteException {
5979                     if (appInfo != null) {
5980                         synchronized (ActivityManagerService.this) {
5981                             finishForceStopPackageLocked(packageName, appInfo.uid);
5982                         }
5983                     }
5984                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5985                             Uri.fromParts("package", packageName, null));
5986                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5987                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5988                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5989                     if (isInstantApp) {
5990                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5991                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5992                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5993                                 resolvedUserId);
5994                     } else {
5995                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5996                                 null, null, null, null, false, false, resolvedUserId);
5997                     }
5998
5999                     if (observer != null) {
6000                         observer.onRemoveCompleted(packageName, succeeded);
6001                     }
6002                 }
6003             };
6004
6005             try {
6006                 // Clear application user data
6007                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6008
6009                 if (appInfo != null) {
6010                     synchronized (this) {
6011                         // Remove all permissions granted from/to this package
6012                         removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6013                     }
6014
6015                     // Reset notification settings.
6016                     INotificationManager inm = NotificationManager.getService();
6017                     inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6018                 }
6019             } catch (RemoteException e) {
6020             }
6021         } finally {
6022             Binder.restoreCallingIdentity(callingId);
6023         }
6024         return true;
6025     }
6026
6027     @Override
6028     public void killBackgroundProcesses(final String packageName, int userId) {
6029         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6030                 != PackageManager.PERMISSION_GRANTED &&
6031                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6032                         != PackageManager.PERMISSION_GRANTED) {
6033             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6034                     + Binder.getCallingPid()
6035                     + ", uid=" + Binder.getCallingUid()
6036                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6037             Slog.w(TAG, msg);
6038             throw new SecurityException(msg);
6039         }
6040
6041         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6042                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6043         long callingId = Binder.clearCallingIdentity();
6044         try {
6045             IPackageManager pm = AppGlobals.getPackageManager();
6046             synchronized(this) {
6047                 int appId = -1;
6048                 try {
6049                     appId = UserHandle.getAppId(
6050                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6051                 } catch (RemoteException e) {
6052                 }
6053                 if (appId == -1) {
6054                     Slog.w(TAG, "Invalid packageName: " + packageName);
6055                     return;
6056                 }
6057                 killPackageProcessesLocked(packageName, appId, userId,
6058                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6059             }
6060         } finally {
6061             Binder.restoreCallingIdentity(callingId);
6062         }
6063     }
6064
6065     @Override
6066     public void killAllBackgroundProcesses() {
6067         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6068                 != PackageManager.PERMISSION_GRANTED) {
6069             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6070                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6071                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6072             Slog.w(TAG, msg);
6073             throw new SecurityException(msg);
6074         }
6075
6076         final long callingId = Binder.clearCallingIdentity();
6077         try {
6078             synchronized (this) {
6079                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6080                 final int NP = mProcessNames.getMap().size();
6081                 for (int ip = 0; ip < NP; ip++) {
6082                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6083                     final int NA = apps.size();
6084                     for (int ia = 0; ia < NA; ia++) {
6085                         final ProcessRecord app = apps.valueAt(ia);
6086                         if (app.persistent) {
6087                             // We don't kill persistent processes.
6088                             continue;
6089                         }
6090                         if (app.removed) {
6091                             procs.add(app);
6092                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6093                             app.removed = true;
6094                             procs.add(app);
6095                         }
6096                     }
6097                 }
6098
6099                 final int N = procs.size();
6100                 for (int i = 0; i < N; i++) {
6101                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6102                 }
6103
6104                 mAllowLowerMemLevel = true;
6105
6106                 updateOomAdjLocked();
6107                 doLowMemReportIfNeededLocked(null);
6108             }
6109         } finally {
6110             Binder.restoreCallingIdentity(callingId);
6111         }
6112     }
6113
6114     /**
6115      * Kills all background processes, except those matching any of the
6116      * specified properties.
6117      *
6118      * @param minTargetSdk the target SDK version at or above which to preserve
6119      *                     processes, or {@code -1} to ignore the target SDK
6120      * @param maxProcState the process state at or below which to preserve
6121      *                     processes, or {@code -1} to ignore the process state
6122      */
6123     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6124         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6125                 != PackageManager.PERMISSION_GRANTED) {
6126             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6127                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6128                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6129             Slog.w(TAG, msg);
6130             throw new SecurityException(msg);
6131         }
6132
6133         final long callingId = Binder.clearCallingIdentity();
6134         try {
6135             synchronized (this) {
6136                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6137                 final int NP = mProcessNames.getMap().size();
6138                 for (int ip = 0; ip < NP; ip++) {
6139                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6140                     final int NA = apps.size();
6141                     for (int ia = 0; ia < NA; ia++) {
6142                         final ProcessRecord app = apps.valueAt(ia);
6143                         if (app.removed) {
6144                             procs.add(app);
6145                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6146                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6147                             app.removed = true;
6148                             procs.add(app);
6149                         }
6150                     }
6151                 }
6152
6153                 final int N = procs.size();
6154                 for (int i = 0; i < N; i++) {
6155                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6156                 }
6157             }
6158         } finally {
6159             Binder.restoreCallingIdentity(callingId);
6160         }
6161     }
6162
6163     @Override
6164     public void forceStopPackage(final String packageName, int userId) {
6165         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6166                 != PackageManager.PERMISSION_GRANTED) {
6167             String msg = "Permission Denial: forceStopPackage() from pid="
6168                     + Binder.getCallingPid()
6169                     + ", uid=" + Binder.getCallingUid()
6170                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6171             Slog.w(TAG, msg);
6172             throw new SecurityException(msg);
6173         }
6174         final int callingPid = Binder.getCallingPid();
6175         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6176                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6177         long callingId = Binder.clearCallingIdentity();
6178         try {
6179             IPackageManager pm = AppGlobals.getPackageManager();
6180             synchronized(this) {
6181                 int[] users = userId == UserHandle.USER_ALL
6182                         ? mUserController.getUsers() : new int[] { userId };
6183                 for (int user : users) {
6184                     int pkgUid = -1;
6185                     try {
6186                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6187                                 user);
6188                     } catch (RemoteException e) {
6189                     }
6190                     if (pkgUid == -1) {
6191                         Slog.w(TAG, "Invalid packageName: " + packageName);
6192                         continue;
6193                     }
6194                     try {
6195                         pm.setPackageStoppedState(packageName, true, user);
6196                     } catch (RemoteException e) {
6197                     } catch (IllegalArgumentException e) {
6198                         Slog.w(TAG, "Failed trying to unstop package "
6199                                 + packageName + ": " + e);
6200                     }
6201                     if (mUserController.isUserRunningLocked(user, 0)) {
6202                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6203                         finishForceStopPackageLocked(packageName, pkgUid);
6204                     }
6205                 }
6206             }
6207         } finally {
6208             Binder.restoreCallingIdentity(callingId);
6209         }
6210     }
6211
6212     @Override
6213     public void addPackageDependency(String packageName) {
6214         synchronized (this) {
6215             int callingPid = Binder.getCallingPid();
6216             if (callingPid == myPid()) {
6217                 //  Yeah, um, no.
6218                 return;
6219             }
6220             ProcessRecord proc;
6221             synchronized (mPidsSelfLocked) {
6222                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6223             }
6224             if (proc != null) {
6225                 if (proc.pkgDeps == null) {
6226                     proc.pkgDeps = new ArraySet<String>(1);
6227                 }
6228                 proc.pkgDeps.add(packageName);
6229             }
6230         }
6231     }
6232
6233     /*
6234      * The pkg name and app id have to be specified.
6235      */
6236     @Override
6237     public void killApplication(String pkg, int appId, int userId, String reason) {
6238         if (pkg == null) {
6239             return;
6240         }
6241         // Make sure the uid is valid.
6242         if (appId < 0) {
6243             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6244             return;
6245         }
6246         int callerUid = Binder.getCallingUid();
6247         // Only the system server can kill an application
6248         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6249             // Post an aysnc message to kill the application
6250             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6251             msg.arg1 = appId;
6252             msg.arg2 = userId;
6253             Bundle bundle = new Bundle();
6254             bundle.putString("pkg", pkg);
6255             bundle.putString("reason", reason);
6256             msg.obj = bundle;
6257             mHandler.sendMessage(msg);
6258         } else {
6259             throw new SecurityException(callerUid + " cannot kill pkg: " +
6260                     pkg);
6261         }
6262     }
6263
6264     @Override
6265     public void closeSystemDialogs(String reason) {
6266         enforceNotIsolatedCaller("closeSystemDialogs");
6267
6268         final int pid = Binder.getCallingPid();
6269         final int uid = Binder.getCallingUid();
6270         final long origId = Binder.clearCallingIdentity();
6271         try {
6272             synchronized (this) {
6273                 // Only allow this from foreground processes, so that background
6274                 // applications can't abuse it to prevent system UI from being shown.
6275                 if (uid >= FIRST_APPLICATION_UID) {
6276                     ProcessRecord proc;
6277                     synchronized (mPidsSelfLocked) {
6278                         proc = mPidsSelfLocked.get(pid);
6279                     }
6280                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6281                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6282                                 + " from background process " + proc);
6283                         return;
6284                     }
6285                 }
6286                 closeSystemDialogsLocked(reason);
6287             }
6288         } finally {
6289             Binder.restoreCallingIdentity(origId);
6290         }
6291     }
6292
6293     void closeSystemDialogsLocked(String reason) {
6294         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6295         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6296                 | Intent.FLAG_RECEIVER_FOREGROUND);
6297         if (reason != null) {
6298             intent.putExtra("reason", reason);
6299         }
6300         mWindowManager.closeSystemDialogs(reason);
6301
6302         mStackSupervisor.closeSystemDialogsLocked();
6303
6304         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6305                 AppOpsManager.OP_NONE, null, false, false,
6306                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6307     }
6308
6309     @Override
6310     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6311         enforceNotIsolatedCaller("getProcessMemoryInfo");
6312         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6313         for (int i=pids.length-1; i>=0; i--) {
6314             ProcessRecord proc;
6315             int oomAdj;
6316             synchronized (this) {
6317                 synchronized (mPidsSelfLocked) {
6318                     proc = mPidsSelfLocked.get(pids[i]);
6319                     oomAdj = proc != null ? proc.setAdj : 0;
6320                 }
6321             }
6322             infos[i] = new Debug.MemoryInfo();
6323             Debug.getMemoryInfo(pids[i], infos[i]);
6324             if (proc != null) {
6325                 synchronized (this) {
6326                     if (proc.thread != null && proc.setAdj == oomAdj) {
6327                         // Record this for posterity if the process has been stable.
6328                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6329                                 infos[i].getTotalUss(), false, proc.pkgList);
6330                     }
6331                 }
6332             }
6333         }
6334         return infos;
6335     }
6336
6337     @Override
6338     public long[] getProcessPss(int[] pids) {
6339         enforceNotIsolatedCaller("getProcessPss");
6340         long[] pss = new long[pids.length];
6341         for (int i=pids.length-1; i>=0; i--) {
6342             ProcessRecord proc;
6343             int oomAdj;
6344             synchronized (this) {
6345                 synchronized (mPidsSelfLocked) {
6346                     proc = mPidsSelfLocked.get(pids[i]);
6347                     oomAdj = proc != null ? proc.setAdj : 0;
6348                 }
6349             }
6350             long[] tmpUss = new long[1];
6351             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6352             if (proc != null) {
6353                 synchronized (this) {
6354                     if (proc.thread != null && proc.setAdj == oomAdj) {
6355                         // Record this for posterity if the process has been stable.
6356                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6357                     }
6358                 }
6359             }
6360         }
6361         return pss;
6362     }
6363
6364     @Override
6365     public void killApplicationProcess(String processName, int uid) {
6366         if (processName == null) {
6367             return;
6368         }
6369
6370         int callerUid = Binder.getCallingUid();
6371         // Only the system server can kill an application
6372         if (callerUid == SYSTEM_UID) {
6373             synchronized (this) {
6374                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6375                 if (app != null && app.thread != null) {
6376                     try {
6377                         app.thread.scheduleSuicide();
6378                     } catch (RemoteException e) {
6379                         // If the other end already died, then our work here is done.
6380                     }
6381                 } else {
6382                     Slog.w(TAG, "Process/uid not found attempting kill of "
6383                             + processName + " / " + uid);
6384                 }
6385             }
6386         } else {
6387             throw new SecurityException(callerUid + " cannot kill app process: " +
6388                     processName);
6389         }
6390     }
6391
6392     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6393         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6394                 false, true, false, false, UserHandle.getUserId(uid), reason);
6395     }
6396
6397     private void finishForceStopPackageLocked(final String packageName, int uid) {
6398         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6399                 Uri.fromParts("package", packageName, null));
6400         if (!mProcessesReady) {
6401             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6402                     | Intent.FLAG_RECEIVER_FOREGROUND);
6403         }
6404         intent.putExtra(Intent.EXTRA_UID, uid);
6405         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6406         broadcastIntentLocked(null, null, intent,
6407                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6408                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6409     }
6410
6411
6412     private final boolean killPackageProcessesLocked(String packageName, int appId,
6413             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6414             boolean doit, boolean evenPersistent, String reason) {
6415         ArrayList<ProcessRecord> procs = new ArrayList<>();
6416
6417         // Remove all processes this package may have touched: all with the
6418         // same UID (except for the system or root user), and all whose name
6419         // matches the package name.
6420         final int NP = mProcessNames.getMap().size();
6421         for (int ip=0; ip<NP; ip++) {
6422             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6423             final int NA = apps.size();
6424             for (int ia=0; ia<NA; ia++) {
6425                 ProcessRecord app = apps.valueAt(ia);
6426                 if (app.persistent && !evenPersistent) {
6427                     // we don't kill persistent processes
6428                     continue;
6429                 }
6430                 if (app.removed) {
6431                     if (doit) {
6432                         procs.add(app);
6433                     }
6434                     continue;
6435                 }
6436
6437                 // Skip process if it doesn't meet our oom adj requirement.
6438                 if (app.setAdj < minOomAdj) {
6439                     continue;
6440                 }
6441
6442                 // If no package is specified, we call all processes under the
6443                 // give user id.
6444                 if (packageName == null) {
6445                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6446                         continue;
6447                     }
6448                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6449                         continue;
6450                     }
6451                 // Package has been specified, we want to hit all processes
6452                 // that match it.  We need to qualify this by the processes
6453                 // that are running under the specified app and user ID.
6454                 } else {
6455                     final boolean isDep = app.pkgDeps != null
6456                             && app.pkgDeps.contains(packageName);
6457                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6458                         continue;
6459                     }
6460                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6461                         continue;
6462                     }
6463                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6464                         continue;
6465                     }
6466                 }
6467
6468                 // Process has passed all conditions, kill it!
6469                 if (!doit) {
6470                     return true;
6471                 }
6472                 app.removed = true;
6473                 procs.add(app);
6474             }
6475         }
6476
6477         int N = procs.size();
6478         for (int i=0; i<N; i++) {
6479             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6480         }
6481         updateOomAdjLocked();
6482         return N > 0;
6483     }
6484
6485     private void cleanupDisabledPackageComponentsLocked(
6486             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6487
6488         Set<String> disabledClasses = null;
6489         boolean packageDisabled = false;
6490         IPackageManager pm = AppGlobals.getPackageManager();
6491
6492         if (changedClasses == null) {
6493             // Nothing changed...
6494             return;
6495         }
6496
6497         // Determine enable/disable state of the package and its components.
6498         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6499         for (int i = changedClasses.length - 1; i >= 0; i--) {
6500             final String changedClass = changedClasses[i];
6501
6502             if (changedClass.equals(packageName)) {
6503                 try {
6504                     // Entire package setting changed
6505                     enabled = pm.getApplicationEnabledSetting(packageName,
6506                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6507                 } catch (Exception e) {
6508                     // No such package/component; probably racing with uninstall.  In any
6509                     // event it means we have nothing further to do here.
6510                     return;
6511                 }
6512                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6513                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6514                 if (packageDisabled) {
6515                     // Entire package is disabled.
6516                     // No need to continue to check component states.
6517                     disabledClasses = null;
6518                     break;
6519                 }
6520             } else {
6521                 try {
6522                     enabled = pm.getComponentEnabledSetting(
6523                             new ComponentName(packageName, changedClass),
6524                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6525                 } catch (Exception e) {
6526                     // As above, probably racing with uninstall.
6527                     return;
6528                 }
6529                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6530                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6531                     if (disabledClasses == null) {
6532                         disabledClasses = new ArraySet<>(changedClasses.length);
6533                     }
6534                     disabledClasses.add(changedClass);
6535                 }
6536             }
6537         }
6538
6539         if (!packageDisabled && disabledClasses == null) {
6540             // Nothing to do here...
6541             return;
6542         }
6543
6544         // Clean-up disabled activities.
6545         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6546                 packageName, disabledClasses, true, false, userId) && mBooted) {
6547             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6548             mStackSupervisor.scheduleIdleLocked();
6549         }
6550
6551         // Clean-up disabled tasks
6552         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6553
6554         // Clean-up disabled services.
6555         mServices.bringDownDisabledPackageServicesLocked(
6556                 packageName, disabledClasses, userId, false, killProcess, true);
6557
6558         // Clean-up disabled providers.
6559         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6560         mProviderMap.collectPackageProvidersLocked(
6561                 packageName, disabledClasses, true, false, userId, providers);
6562         for (int i = providers.size() - 1; i >= 0; i--) {
6563             removeDyingProviderLocked(null, providers.get(i), true);
6564         }
6565
6566         // Clean-up disabled broadcast receivers.
6567         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6568             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6569                     packageName, disabledClasses, userId, true);
6570         }
6571
6572     }
6573
6574     final boolean clearBroadcastQueueForUserLocked(int userId) {
6575         boolean didSomething = false;
6576         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6577             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6578                     null, null, userId, true);
6579         }
6580         return didSomething;
6581     }
6582
6583     final boolean forceStopPackageLocked(String packageName, int appId,
6584             boolean callerWillRestart, boolean purgeCache, boolean doit,
6585             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6586         int i;
6587
6588         if (userId == UserHandle.USER_ALL && packageName == null) {
6589             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6590         }
6591
6592         if (appId < 0 && packageName != null) {
6593             try {
6594                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6595                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6596             } catch (RemoteException e) {
6597             }
6598         }
6599
6600         if (doit) {
6601             if (packageName != null) {
6602                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6603                         + " user=" + userId + ": " + reason);
6604             } else {
6605                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6606             }
6607
6608             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6609         }
6610
6611         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6612                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6613                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6614
6615         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6616
6617         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6618                 packageName, null, doit, evenPersistent, userId)) {
6619             if (!doit) {
6620                 return true;
6621             }
6622             didSomething = true;
6623         }
6624
6625         if (mServices.bringDownDisabledPackageServicesLocked(
6626                 packageName, null, userId, evenPersistent, true, doit)) {
6627             if (!doit) {
6628                 return true;
6629             }
6630             didSomething = true;
6631         }
6632
6633         if (packageName == null) {
6634             // Remove all sticky broadcasts from this user.
6635             mStickyBroadcasts.remove(userId);
6636         }
6637
6638         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6639         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6640                 userId, providers)) {
6641             if (!doit) {
6642                 return true;
6643             }
6644             didSomething = true;
6645         }
6646         for (i = providers.size() - 1; i >= 0; i--) {
6647             removeDyingProviderLocked(null, providers.get(i), true);
6648         }
6649
6650         // Remove transient permissions granted from/to this package/user
6651         removeUriPermissionsForPackageLocked(packageName, userId, false);
6652
6653         if (doit) {
6654             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6655                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6656                         packageName, null, userId, doit);
6657             }
6658         }
6659
6660         if (packageName == null || uninstalling) {
6661             // Remove pending intents.  For now we only do this when force
6662             // stopping users, because we have some problems when doing this
6663             // for packages -- app widgets are not currently cleaned up for
6664             // such packages, so they can be left with bad pending intents.
6665             if (mIntentSenderRecords.size() > 0) {
6666                 Iterator<WeakReference<PendingIntentRecord>> it
6667                         = mIntentSenderRecords.values().iterator();
6668                 while (it.hasNext()) {
6669                     WeakReference<PendingIntentRecord> wpir = it.next();
6670                     if (wpir == null) {
6671                         it.remove();
6672                         continue;
6673                     }
6674                     PendingIntentRecord pir = wpir.get();
6675                     if (pir == null) {
6676                         it.remove();
6677                         continue;
6678                     }
6679                     if (packageName == null) {
6680                         // Stopping user, remove all objects for the user.
6681                         if (pir.key.userId != userId) {
6682                             // Not the same user, skip it.
6683                             continue;
6684                         }
6685                     } else {
6686                         if (UserHandle.getAppId(pir.uid) != appId) {
6687                             // Different app id, skip it.
6688                             continue;
6689                         }
6690                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6691                             // Different user, skip it.
6692                             continue;
6693                         }
6694                         if (!pir.key.packageName.equals(packageName)) {
6695                             // Different package, skip it.
6696                             continue;
6697                         }
6698                     }
6699                     if (!doit) {
6700                         return true;
6701                     }
6702                     didSomething = true;
6703                     it.remove();
6704                     makeIntentSenderCanceledLocked(pir);
6705                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6706                         pir.key.activity.pendingResults.remove(pir.ref);
6707                     }
6708                 }
6709             }
6710         }
6711
6712         if (doit) {
6713             if (purgeCache && packageName != null) {
6714                 AttributeCache ac = AttributeCache.instance();
6715                 if (ac != null) {
6716                     ac.removePackage(packageName);
6717                 }
6718             }
6719             if (mBooted) {
6720                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6721                 mStackSupervisor.scheduleIdleLocked();
6722             }
6723         }
6724
6725         return didSomething;
6726     }
6727
6728     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6729         return removeProcessNameLocked(name, uid, null);
6730     }
6731
6732     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6733             final ProcessRecord expecting) {
6734         ProcessRecord old = mProcessNames.get(name, uid);
6735         // Only actually remove when the currently recorded value matches the
6736         // record that we expected; if it doesn't match then we raced with a
6737         // newly created process and we don't want to destroy the new one.
6738         if ((expecting == null) || (old == expecting)) {
6739             mProcessNames.remove(name, uid);
6740         }
6741         if (old != null && old.uidRecord != null) {
6742             old.uidRecord.numProcs--;
6743             if (old.uidRecord.numProcs == 0) {
6744                 // No more processes using this uid, tell clients it is gone.
6745                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6746                         "No more processes in " + old.uidRecord);
6747                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6748                 EventLogTags.writeAmUidStopped(uid);
6749                 mActiveUids.remove(uid);
6750                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6751             }
6752             old.uidRecord = null;
6753         }
6754         mIsolatedProcesses.remove(uid);
6755         return old;
6756     }
6757
6758     private final void addProcessNameLocked(ProcessRecord proc) {
6759         // We shouldn't already have a process under this name, but just in case we
6760         // need to clean up whatever may be there now.
6761         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6762         if (old == proc && proc.persistent) {
6763             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6764             Slog.w(TAG, "Re-adding persistent process " + proc);
6765         } else if (old != null) {
6766             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6767         }
6768         UidRecord uidRec = mActiveUids.get(proc.uid);
6769         if (uidRec == null) {
6770             uidRec = new UidRecord(proc.uid);
6771             // This is the first appearance of the uid, report it now!
6772             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6773                     "Creating new process uid: " + uidRec);
6774             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6775                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6776                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6777             }
6778             uidRec.updateHasInternetPermission();
6779             mActiveUids.put(proc.uid, uidRec);
6780             EventLogTags.writeAmUidRunning(uidRec.uid);
6781             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6782         }
6783         proc.uidRecord = uidRec;
6784
6785         // Reset render thread tid if it was already set, so new process can set it again.
6786         proc.renderThreadTid = 0;
6787         uidRec.numProcs++;
6788         mProcessNames.put(proc.processName, proc.uid, proc);
6789         if (proc.isolated) {
6790             mIsolatedProcesses.put(proc.uid, proc);
6791         }
6792     }
6793
6794     boolean removeProcessLocked(ProcessRecord app,
6795             boolean callerWillRestart, boolean allowRestart, String reason) {
6796         final String name = app.processName;
6797         final int uid = app.uid;
6798         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6799             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6800
6801         ProcessRecord old = mProcessNames.get(name, uid);
6802         if (old != app) {
6803             // This process is no longer active, so nothing to do.
6804             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6805             return false;
6806         }
6807         removeProcessNameLocked(name, uid);
6808         if (mHeavyWeightProcess == app) {
6809             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6810                     mHeavyWeightProcess.userId, 0));
6811             mHeavyWeightProcess = null;
6812         }
6813         boolean needRestart = false;
6814         if (app.pid > 0 && app.pid != MY_PID) {
6815             int pid = app.pid;
6816             synchronized (mPidsSelfLocked) {
6817                 mPidsSelfLocked.remove(pid);
6818                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6819             }
6820             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6821             boolean willRestart = false;
6822             if (app.persistent && !app.isolated) {
6823                 if (!callerWillRestart) {
6824                     willRestart = true;
6825                 } else {
6826                     needRestart = true;
6827                 }
6828             }
6829             app.kill(reason, true);
6830             if (app.isolated) {
6831                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6832                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6833             }
6834             handleAppDiedLocked(app, willRestart, allowRestart);
6835             if (willRestart) {
6836                 removeLruProcessLocked(app);
6837                 addAppLocked(app.info, null, false, null /* ABI override */);
6838             }
6839         } else {
6840             mRemovedProcesses.add(app);
6841         }
6842
6843         return needRestart;
6844     }
6845
6846     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6847         cleanupAppInLaunchingProvidersLocked(app, true);
6848         removeProcessLocked(app, false, true, "timeout publishing content providers");
6849     }
6850
6851     private final void processStartTimedOutLocked(ProcessRecord app) {
6852         final int pid = app.pid;
6853         boolean gone = false;
6854         synchronized (mPidsSelfLocked) {
6855             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6856             if (knownApp != null && knownApp.thread == null) {
6857                 mPidsSelfLocked.remove(pid);
6858                 gone = true;
6859             }
6860         }
6861
6862         if (gone) {
6863             Slog.w(TAG, "Process " + app + " failed to attach");
6864             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6865                     pid, app.uid, app.processName);
6866             removeProcessNameLocked(app.processName, app.uid);
6867             if (mHeavyWeightProcess == app) {
6868                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6869                         mHeavyWeightProcess.userId, 0));
6870                 mHeavyWeightProcess = null;
6871             }
6872             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6873             // Take care of any launching providers waiting for this process.
6874             cleanupAppInLaunchingProvidersLocked(app, true);
6875             // Take care of any services that are waiting for the process.
6876             mServices.processStartTimedOutLocked(app);
6877             app.kill("start timeout", true);
6878             if (app.isolated) {
6879                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6880             }
6881             removeLruProcessLocked(app);
6882             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6883                 Slog.w(TAG, "Unattached app died before backup, skipping");
6884                 mHandler.post(new Runnable() {
6885                 @Override
6886                     public void run(){
6887                         try {
6888                             IBackupManager bm = IBackupManager.Stub.asInterface(
6889                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6890                             bm.agentDisconnected(app.info.packageName);
6891                         } catch (RemoteException e) {
6892                             // Can't happen; the backup manager is local
6893                         }
6894                     }
6895                 });
6896             }
6897             if (isPendingBroadcastProcessLocked(pid)) {
6898                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6899                 skipPendingBroadcastLocked(pid);
6900             }
6901         } else {
6902             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6903         }
6904     }
6905
6906     private final boolean attachApplicationLocked(IApplicationThread thread,
6907             int pid) {
6908
6909         // Find the application record that is being attached...  either via
6910         // the pid if we are running in multiple processes, or just pull the
6911         // next app record if we are emulating process with anonymous threads.
6912         ProcessRecord app;
6913         long startTime = SystemClock.uptimeMillis();
6914         if (pid != MY_PID && pid >= 0) {
6915             synchronized (mPidsSelfLocked) {
6916                 app = mPidsSelfLocked.get(pid);
6917             }
6918         } else {
6919             app = null;
6920         }
6921
6922         if (app == null) {
6923             Slog.w(TAG, "No pending application record for pid " + pid
6924                     + " (IApplicationThread " + thread + "); dropping process");
6925             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6926             if (pid > 0 && pid != MY_PID) {
6927                 killProcessQuiet(pid);
6928                 //TODO: killProcessGroup(app.info.uid, pid);
6929             } else {
6930                 try {
6931                     thread.scheduleExit();
6932                 } catch (Exception e) {
6933                     // Ignore exceptions.
6934                 }
6935             }
6936             return false;
6937         }
6938
6939         // If this application record is still attached to a previous
6940         // process, clean it up now.
6941         if (app.thread != null) {
6942             handleAppDiedLocked(app, true, true);
6943         }
6944
6945         // Tell the process all about itself.
6946
6947         if (DEBUG_ALL) Slog.v(
6948                 TAG, "Binding process pid " + pid + " to record " + app);
6949
6950         final String processName = app.processName;
6951         try {
6952             AppDeathRecipient adr = new AppDeathRecipient(
6953                     app, pid, thread);
6954             thread.asBinder().linkToDeath(adr, 0);
6955             app.deathRecipient = adr;
6956         } catch (RemoteException e) {
6957             app.resetPackageList(mProcessStats);
6958             startProcessLocked(app, "link fail", processName);
6959             return false;
6960         }
6961
6962         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6963
6964         app.makeActive(thread, mProcessStats);
6965         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6966         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6967         app.forcingToImportant = null;
6968         updateProcessForegroundLocked(app, false, false);
6969         app.hasShownUi = false;
6970         app.debugging = false;
6971         app.cached = false;
6972         app.killedByAm = false;
6973         app.killed = false;
6974
6975
6976         // We carefully use the same state that PackageManager uses for
6977         // filtering, since we use this flag to decide if we need to install
6978         // providers when user is unlocked later
6979         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6980
6981         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6982
6983         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6984         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6985
6986         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6987             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6988             msg.obj = app;
6989             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6990         }
6991
6992         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6993
6994         if (!normalMode) {
6995             Slog.i(TAG, "Launching preboot mode app: " + app);
6996         }
6997
6998         if (DEBUG_ALL) Slog.v(
6999             TAG, "New app record " + app
7000             + " thread=" + thread.asBinder() + " pid=" + pid);
7001         try {
7002             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7003             if (mDebugApp != null && mDebugApp.equals(processName)) {
7004                 testMode = mWaitForDebugger
7005                     ? ApplicationThreadConstants.DEBUG_WAIT
7006                     : ApplicationThreadConstants.DEBUG_ON;
7007                 app.debugging = true;
7008                 if (mDebugTransient) {
7009                     mDebugApp = mOrigDebugApp;
7010                     mWaitForDebugger = mOrigWaitForDebugger;
7011                 }
7012             }
7013
7014             ProfilerInfo profilerInfo = null;
7015             String preBindAgent = null;
7016             if (mProfileApp != null && mProfileApp.equals(processName)) {
7017                 mProfileProc = app;
7018                 if (mProfilerInfo != null) {
7019                     // Send a profiler info object to the app if either a file is given, or
7020                     // an agent should be loaded at bind-time.
7021                     boolean needsInfo = mProfilerInfo.profileFile != null
7022                             || mProfilerInfo.attachAgentDuringBind;
7023                     profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7024                     if (!mProfilerInfo.attachAgentDuringBind) {
7025                         preBindAgent = mProfilerInfo.agent;
7026                     }
7027                 }
7028             } else if (app.instr != null && app.instr.mProfileFile != null) {
7029                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7030                         null, false);
7031             }
7032
7033             boolean enableTrackAllocation = false;
7034             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7035                 enableTrackAllocation = true;
7036                 mTrackAllocationApp = null;
7037             }
7038
7039             // If the app is being launched for restore or full backup, set it up specially
7040             boolean isRestrictedBackupMode = false;
7041             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7042                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7043                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7044                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7045                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7046             }
7047
7048             if (app.instr != null) {
7049                 notifyPackageUse(app.instr.mClass.getPackageName(),
7050                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7051             }
7052             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7053                     + processName + " with config " + getGlobalConfiguration());
7054             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7055             app.compat = compatibilityInfoForPackageLocked(appInfo);
7056
7057             if (profilerInfo != null && profilerInfo.profileFd != null) {
7058                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7059             }
7060
7061             // We deprecated Build.SERIAL and it is not accessible to
7062             // apps that target the v2 security sandbox. Since access to
7063             // the serial is now behind a permission we push down the value.
7064             String buildSerial = appInfo.targetSandboxVersion < 2
7065                     ? sTheRealBuildSerial : Build.UNKNOWN;
7066
7067             // Check if this is a secondary process that should be incorporated into some
7068             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7069             // stuff above because profiling can currently happen only in the primary
7070             // instrumentation process.)
7071             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7072                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7073                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7074                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7075                         if (aInstr.mTargetProcesses.length == 0) {
7076                             // This is the wildcard mode, where every process brought up for
7077                             // the target instrumentation should be included.
7078                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7079                                 app.instr = aInstr;
7080                                 aInstr.mRunningProcesses.add(app);
7081                             }
7082                         } else {
7083                             for (String proc : aInstr.mTargetProcesses) {
7084                                 if (proc.equals(app.processName)) {
7085                                     app.instr = aInstr;
7086                                     aInstr.mRunningProcesses.add(app);
7087                                     break;
7088                                 }
7089                             }
7090                         }
7091                     }
7092                 }
7093             }
7094
7095             // If we were asked to attach an agent on startup, do so now, before we're binding
7096             // application code.
7097             if (preBindAgent != null) {
7098                 thread.attachAgent(preBindAgent);
7099             }
7100
7101             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7102             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7103             if (app.instr != null) {
7104                 thread.bindApplication(processName, appInfo, providers,
7105                         app.instr.mClass,
7106                         profilerInfo, app.instr.mArguments,
7107                         app.instr.mWatcher,
7108                         app.instr.mUiAutomationConnection, testMode,
7109                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7110                         isRestrictedBackupMode || !normalMode, app.persistent,
7111                         new Configuration(getGlobalConfiguration()), app.compat,
7112                         getCommonServicesLocked(app.isolated),
7113                         mCoreSettingsObserver.getCoreSettingsLocked(),
7114                         buildSerial);
7115             } else {
7116                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7117                         null, null, null, testMode,
7118                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7119                         isRestrictedBackupMode || !normalMode, app.persistent,
7120                         new Configuration(getGlobalConfiguration()), app.compat,
7121                         getCommonServicesLocked(app.isolated),
7122                         mCoreSettingsObserver.getCoreSettingsLocked(),
7123                         buildSerial);
7124             }
7125
7126             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7127             updateLruProcessLocked(app, false, null);
7128             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7129             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7130         } catch (Exception e) {
7131             // todo: Yikes!  What should we do?  For now we will try to
7132             // start another process, but that could easily get us in
7133             // an infinite loop of restarting processes...
7134             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7135
7136             app.resetPackageList(mProcessStats);
7137             app.unlinkDeathRecipient();
7138             startProcessLocked(app, "bind fail", processName);
7139             return false;
7140         }
7141
7142         // Remove this record from the list of starting applications.
7143         mPersistentStartingProcesses.remove(app);
7144         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7145                 "Attach application locked removing on hold: " + app);
7146         mProcessesOnHold.remove(app);
7147
7148         boolean badApp = false;
7149         boolean didSomething = false;
7150
7151         // See if the top visible activity is waiting to run in this process...
7152         if (normalMode) {
7153             try {
7154                 if (mStackSupervisor.attachApplicationLocked(app)) {
7155                     didSomething = true;
7156                 }
7157             } catch (Exception e) {
7158                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7159                 badApp = true;
7160             }
7161         }
7162
7163         // Find any services that should be running in this process...
7164         if (!badApp) {
7165             try {
7166                 didSomething |= mServices.attachApplicationLocked(app, processName);
7167                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7168             } catch (Exception e) {
7169                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7170                 badApp = true;
7171             }
7172         }
7173
7174         // Check if a next-broadcast receiver is in this process...
7175         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7176             try {
7177                 didSomething |= sendPendingBroadcastsLocked(app);
7178                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7179             } catch (Exception e) {
7180                 // If the app died trying to launch the receiver we declare it 'bad'
7181                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7182                 badApp = true;
7183             }
7184         }
7185
7186         // Check whether the next backup agent is in this process...
7187         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7188             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7189                     "New app is backup target, launching agent for " + app);
7190             notifyPackageUse(mBackupTarget.appInfo.packageName,
7191                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7192             try {
7193                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7194                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7195                         mBackupTarget.backupMode);
7196             } catch (Exception e) {
7197                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7198                 badApp = true;
7199             }
7200         }
7201
7202         if (badApp) {
7203             app.kill("error during init", true);
7204             handleAppDiedLocked(app, false, true);
7205             return false;
7206         }
7207
7208         if (!didSomething) {
7209             updateOomAdjLocked();
7210             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7211         }
7212
7213         return true;
7214     }
7215
7216     @Override
7217     public final void attachApplication(IApplicationThread thread) {
7218         synchronized (this) {
7219             int callingPid = Binder.getCallingPid();
7220             final long origId = Binder.clearCallingIdentity();
7221             attachApplicationLocked(thread, callingPid);
7222             Binder.restoreCallingIdentity(origId);
7223         }
7224     }
7225
7226     @Override
7227     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7228         final long origId = Binder.clearCallingIdentity();
7229         synchronized (this) {
7230             ActivityStack stack = ActivityRecord.getStackLocked(token);
7231             if (stack != null) {
7232                 ActivityRecord r =
7233                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7234                                 false /* processPausingActivities */, config);
7235                 if (stopProfiling) {
7236                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7237                         clearProfilerLocked();
7238                     }
7239                 }
7240             }
7241         }
7242         Binder.restoreCallingIdentity(origId);
7243     }
7244
7245     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7246         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7247                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7248     }
7249
7250     void enableScreenAfterBoot() {
7251         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7252                 SystemClock.uptimeMillis());
7253         mWindowManager.enableScreenAfterBoot();
7254
7255         synchronized (this) {
7256             updateEventDispatchingLocked();
7257         }
7258     }
7259
7260     @Override
7261     public void showBootMessage(final CharSequence msg, final boolean always) {
7262         if (Binder.getCallingUid() != myUid()) {
7263             throw new SecurityException();
7264         }
7265         mWindowManager.showBootMessage(msg, always);
7266     }
7267
7268     @Override
7269     public void keyguardGoingAway(int flags) {
7270         enforceNotIsolatedCaller("keyguardGoingAway");
7271         final long token = Binder.clearCallingIdentity();
7272         try {
7273             synchronized (this) {
7274                 mKeyguardController.keyguardGoingAway(flags);
7275             }
7276         } finally {
7277             Binder.restoreCallingIdentity(token);
7278         }
7279     }
7280
7281     /**
7282      * @return whther the keyguard is currently locked.
7283      */
7284     boolean isKeyguardLocked() {
7285         return mKeyguardController.isKeyguardLocked();
7286     }
7287
7288     final void finishBooting() {
7289         synchronized (this) {
7290             if (!mBootAnimationComplete) {
7291                 mCallFinishBooting = true;
7292                 return;
7293             }
7294             mCallFinishBooting = false;
7295         }
7296
7297         ArraySet<String> completedIsas = new ArraySet<String>();
7298         for (String abi : Build.SUPPORTED_ABIS) {
7299             zygoteProcess.establishZygoteConnectionForAbi(abi);
7300             final String instructionSet = VMRuntime.getInstructionSet(abi);
7301             if (!completedIsas.contains(instructionSet)) {
7302                 try {
7303                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7304                 } catch (InstallerException e) {
7305                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7306                             e.getMessage() +")");
7307                 }
7308                 completedIsas.add(instructionSet);
7309             }
7310         }
7311
7312         IntentFilter pkgFilter = new IntentFilter();
7313         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7314         pkgFilter.addDataScheme("package");
7315         mContext.registerReceiver(new BroadcastReceiver() {
7316             @Override
7317             public void onReceive(Context context, Intent intent) {
7318                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7319                 if (pkgs != null) {
7320                     for (String pkg : pkgs) {
7321                         synchronized (ActivityManagerService.this) {
7322                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7323                                     0, "query restart")) {
7324                                 setResultCode(Activity.RESULT_OK);
7325                                 return;
7326                             }
7327                         }
7328                     }
7329                 }
7330             }
7331         }, pkgFilter);
7332
7333         IntentFilter dumpheapFilter = new IntentFilter();
7334         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7335         mContext.registerReceiver(new BroadcastReceiver() {
7336             @Override
7337             public void onReceive(Context context, Intent intent) {
7338                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7339                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7340                 } else {
7341                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7342                 }
7343             }
7344         }, dumpheapFilter);
7345
7346         // Let system services know.
7347         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7348
7349         synchronized (this) {
7350             // Ensure that any processes we had put on hold are now started
7351             // up.
7352             final int NP = mProcessesOnHold.size();
7353             if (NP > 0) {
7354                 ArrayList<ProcessRecord> procs =
7355                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7356                 for (int ip=0; ip<NP; ip++) {
7357                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7358                             + procs.get(ip));
7359                     startProcessLocked(procs.get(ip), "on-hold", null);
7360                 }
7361             }
7362
7363             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7364                 // Start looking for apps that are abusing wake locks.
7365                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7366                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7367                 // Tell anyone interested that we are done booting!
7368                 SystemProperties.set("sys.boot_completed", "1");
7369
7370                 // And trigger dev.bootcomplete if we are not showing encryption progress
7371                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7372                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7373                     SystemProperties.set("dev.bootcomplete", "1");
7374                 }
7375                 mUserController.sendBootCompletedLocked(
7376                         new IIntentReceiver.Stub() {
7377                             @Override
7378                             public void performReceive(Intent intent, int resultCode,
7379                                     String data, Bundle extras, boolean ordered,
7380                                     boolean sticky, int sendingUser) {
7381                                 synchronized (ActivityManagerService.this) {
7382                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7383                                             true, false);
7384                                 }
7385                             }
7386                         });
7387                 scheduleStartProfilesLocked();
7388             }
7389         }
7390     }
7391
7392     @Override
7393     public void bootAnimationComplete() {
7394         final boolean callFinishBooting;
7395         synchronized (this) {
7396             callFinishBooting = mCallFinishBooting;
7397             mBootAnimationComplete = true;
7398         }
7399         if (callFinishBooting) {
7400             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7401             finishBooting();
7402             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7403         }
7404     }
7405
7406     final void ensureBootCompleted() {
7407         boolean booting;
7408         boolean enableScreen;
7409         synchronized (this) {
7410             booting = mBooting;
7411             mBooting = false;
7412             enableScreen = !mBooted;
7413             mBooted = true;
7414         }
7415
7416         if (booting) {
7417             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7418             finishBooting();
7419             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7420         }
7421
7422         if (enableScreen) {
7423             enableScreenAfterBoot();
7424         }
7425     }
7426
7427     @Override
7428     public final void activityResumed(IBinder token) {
7429         final long origId = Binder.clearCallingIdentity();
7430         synchronized(this) {
7431             ActivityRecord.activityResumedLocked(token);
7432             mWindowManager.notifyAppResumedFinished(token);
7433         }
7434         Binder.restoreCallingIdentity(origId);
7435     }
7436
7437     @Override
7438     public final void activityPaused(IBinder token) {
7439         final long origId = Binder.clearCallingIdentity();
7440         synchronized(this) {
7441             ActivityStack stack = ActivityRecord.getStackLocked(token);
7442             if (stack != null) {
7443                 stack.activityPausedLocked(token, false);
7444             }
7445         }
7446         Binder.restoreCallingIdentity(origId);
7447     }
7448
7449     @Override
7450     public final void activityStopped(IBinder token, Bundle icicle,
7451             PersistableBundle persistentState, CharSequence description) {
7452         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7453
7454         // Refuse possible leaked file descriptors
7455         if (icicle != null && icicle.hasFileDescriptors()) {
7456             throw new IllegalArgumentException("File descriptors passed in Bundle");
7457         }
7458
7459         final long origId = Binder.clearCallingIdentity();
7460
7461         synchronized (this) {
7462             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7463             if (r != null) {
7464                 r.activityStoppedLocked(icicle, persistentState, description);
7465             }
7466         }
7467
7468         trimApplications();
7469
7470         Binder.restoreCallingIdentity(origId);
7471     }
7472
7473     @Override
7474     public final void activityDestroyed(IBinder token) {
7475         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7476         synchronized (this) {
7477             ActivityStack stack = ActivityRecord.getStackLocked(token);
7478             if (stack != null) {
7479                 stack.activityDestroyedLocked(token, "activityDestroyed");
7480             }
7481         }
7482     }
7483
7484     @Override
7485     public final void activityRelaunched(IBinder token) {
7486         final long origId = Binder.clearCallingIdentity();
7487         synchronized (this) {
7488             mStackSupervisor.activityRelaunchedLocked(token);
7489         }
7490         Binder.restoreCallingIdentity(origId);
7491     }
7492
7493     @Override
7494     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7495             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7496         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7497                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7498         synchronized (this) {
7499             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7500             if (record == null) {
7501                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7502                         + "found for: " + token);
7503             }
7504             record.setSizeConfigurations(horizontalSizeConfiguration,
7505                     verticalSizeConfigurations, smallestSizeConfigurations);
7506         }
7507     }
7508
7509     @Override
7510     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7511         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7512     }
7513
7514     @Override
7515     public final void notifyEnterAnimationComplete(IBinder token) {
7516         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7517     }
7518
7519     @Override
7520     public String getCallingPackage(IBinder token) {
7521         synchronized (this) {
7522             ActivityRecord r = getCallingRecordLocked(token);
7523             return r != null ? r.info.packageName : null;
7524         }
7525     }
7526
7527     @Override
7528     public ComponentName getCallingActivity(IBinder token) {
7529         synchronized (this) {
7530             ActivityRecord r = getCallingRecordLocked(token);
7531             return r != null ? r.intent.getComponent() : null;
7532         }
7533     }
7534
7535     private ActivityRecord getCallingRecordLocked(IBinder token) {
7536         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7537         if (r == null) {
7538             return null;
7539         }
7540         return r.resultTo;
7541     }
7542
7543     @Override
7544     public ComponentName getActivityClassForToken(IBinder token) {
7545         synchronized(this) {
7546             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7547             if (r == null) {
7548                 return null;
7549             }
7550             return r.intent.getComponent();
7551         }
7552     }
7553
7554     @Override
7555     public String getPackageForToken(IBinder token) {
7556         synchronized(this) {
7557             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7558             if (r == null) {
7559                 return null;
7560             }
7561             return r.packageName;
7562         }
7563     }
7564
7565     @Override
7566     public boolean isRootVoiceInteraction(IBinder token) {
7567         synchronized(this) {
7568             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7569             if (r == null) {
7570                 return false;
7571             }
7572             return r.rootVoiceInteraction;
7573         }
7574     }
7575
7576     @Override
7577     public IIntentSender getIntentSender(int type,
7578             String packageName, IBinder token, String resultWho,
7579             int requestCode, Intent[] intents, String[] resolvedTypes,
7580             int flags, Bundle bOptions, int userId) {
7581         enforceNotIsolatedCaller("getIntentSender");
7582         // Refuse possible leaked file descriptors
7583         if (intents != null) {
7584             if (intents.length < 1) {
7585                 throw new IllegalArgumentException("Intents array length must be >= 1");
7586             }
7587             for (int i=0; i<intents.length; i++) {
7588                 Intent intent = intents[i];
7589                 if (intent != null) {
7590                     if (intent.hasFileDescriptors()) {
7591                         throw new IllegalArgumentException("File descriptors passed in Intent");
7592                     }
7593                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7594                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7595                         throw new IllegalArgumentException(
7596                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7597                     }
7598                     intents[i] = new Intent(intent);
7599                 }
7600             }
7601             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7602                 throw new IllegalArgumentException(
7603                         "Intent array length does not match resolvedTypes length");
7604             }
7605         }
7606         if (bOptions != null) {
7607             if (bOptions.hasFileDescriptors()) {
7608                 throw new IllegalArgumentException("File descriptors passed in options");
7609             }
7610         }
7611
7612         synchronized(this) {
7613             int callingUid = Binder.getCallingUid();
7614             int origUserId = userId;
7615             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7616                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7617                     ALLOW_NON_FULL, "getIntentSender", null);
7618             if (origUserId == UserHandle.USER_CURRENT) {
7619                 // We don't want to evaluate this until the pending intent is
7620                 // actually executed.  However, we do want to always do the
7621                 // security checking for it above.
7622                 userId = UserHandle.USER_CURRENT;
7623             }
7624             try {
7625                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7626                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7627                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7628                     if (!UserHandle.isSameApp(callingUid, uid)) {
7629                         String msg = "Permission Denial: getIntentSender() from pid="
7630                             + Binder.getCallingPid()
7631                             + ", uid=" + Binder.getCallingUid()
7632                             + ", (need uid=" + uid + ")"
7633                             + " is not allowed to send as package " + packageName;
7634                         Slog.w(TAG, msg);
7635                         throw new SecurityException(msg);
7636                     }
7637                 }
7638
7639                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7640                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7641
7642             } catch (RemoteException e) {
7643                 throw new SecurityException(e);
7644             }
7645         }
7646     }
7647
7648     IIntentSender getIntentSenderLocked(int type, String packageName,
7649             int callingUid, int userId, IBinder token, String resultWho,
7650             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7651             Bundle bOptions) {
7652         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7653         ActivityRecord activity = null;
7654         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7655             activity = ActivityRecord.isInStackLocked(token);
7656             if (activity == null) {
7657                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7658                 return null;
7659             }
7660             if (activity.finishing) {
7661                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7662                 return null;
7663             }
7664         }
7665
7666         // We're going to be splicing together extras before sending, so we're
7667         // okay poking into any contained extras.
7668         if (intents != null) {
7669             for (int i = 0; i < intents.length; i++) {
7670                 intents[i].setDefusable(true);
7671             }
7672         }
7673         Bundle.setDefusable(bOptions, true);
7674
7675         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7676         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7677         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7678         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7679                 |PendingIntent.FLAG_UPDATE_CURRENT);
7680
7681         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7682                 type, packageName, activity, resultWho,
7683                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7684         WeakReference<PendingIntentRecord> ref;
7685         ref = mIntentSenderRecords.get(key);
7686         PendingIntentRecord rec = ref != null ? ref.get() : null;
7687         if (rec != null) {
7688             if (!cancelCurrent) {
7689                 if (updateCurrent) {
7690                     if (rec.key.requestIntent != null) {
7691                         rec.key.requestIntent.replaceExtras(intents != null ?
7692                                 intents[intents.length - 1] : null);
7693                     }
7694                     if (intents != null) {
7695                         intents[intents.length-1] = rec.key.requestIntent;
7696                         rec.key.allIntents = intents;
7697                         rec.key.allResolvedTypes = resolvedTypes;
7698                     } else {
7699                         rec.key.allIntents = null;
7700                         rec.key.allResolvedTypes = null;
7701                     }
7702                 }
7703                 return rec;
7704             }
7705             makeIntentSenderCanceledLocked(rec);
7706             mIntentSenderRecords.remove(key);
7707         }
7708         if (noCreate) {
7709             return rec;
7710         }
7711         rec = new PendingIntentRecord(this, key, callingUid);
7712         mIntentSenderRecords.put(key, rec.ref);
7713         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7714             if (activity.pendingResults == null) {
7715                 activity.pendingResults
7716                         = new HashSet<WeakReference<PendingIntentRecord>>();
7717             }
7718             activity.pendingResults.add(rec.ref);
7719         }
7720         return rec;
7721     }
7722
7723     @Override
7724     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7725             Intent intent, String resolvedType,
7726             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7727         if (target instanceof PendingIntentRecord) {
7728             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7729                     whitelistToken, finishedReceiver, requiredPermission, options);
7730         } else {
7731             if (intent == null) {
7732                 // Weird case: someone has given us their own custom IIntentSender, and now
7733                 // they have someone else trying to send to it but of course this isn't
7734                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7735                 // supplying an Intent... but we never want to dispatch a null Intent to
7736                 // a receiver, so um...  let's make something up.
7737                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7738                 intent = new Intent(Intent.ACTION_MAIN);
7739             }
7740             try {
7741                 target.send(code, intent, resolvedType, whitelistToken, null,
7742                         requiredPermission, options);
7743             } catch (RemoteException e) {
7744             }
7745             // Platform code can rely on getting a result back when the send is done, but if
7746             // this intent sender is from outside of the system we can't rely on it doing that.
7747             // So instead we don't give it the result receiver, and instead just directly
7748             // report the finish immediately.
7749             if (finishedReceiver != null) {
7750                 try {
7751                     finishedReceiver.performReceive(intent, 0,
7752                             null, null, false, false, UserHandle.getCallingUserId());
7753                 } catch (RemoteException e) {
7754                 }
7755             }
7756             return 0;
7757         }
7758     }
7759
7760     @Override
7761     public void cancelIntentSender(IIntentSender sender) {
7762         if (!(sender instanceof PendingIntentRecord)) {
7763             return;
7764         }
7765         synchronized(this) {
7766             PendingIntentRecord rec = (PendingIntentRecord)sender;
7767             try {
7768                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7769                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7770                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7771                     String msg = "Permission Denial: cancelIntentSender() from pid="
7772                         + Binder.getCallingPid()
7773                         + ", uid=" + Binder.getCallingUid()
7774                         + " is not allowed to cancel package "
7775                         + rec.key.packageName;
7776                     Slog.w(TAG, msg);
7777                     throw new SecurityException(msg);
7778                 }
7779             } catch (RemoteException e) {
7780                 throw new SecurityException(e);
7781             }
7782             cancelIntentSenderLocked(rec, true);
7783         }
7784     }
7785
7786     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7787         makeIntentSenderCanceledLocked(rec);
7788         mIntentSenderRecords.remove(rec.key);
7789         if (cleanActivity && rec.key.activity != null) {
7790             rec.key.activity.pendingResults.remove(rec.ref);
7791         }
7792     }
7793
7794     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7795         rec.canceled = true;
7796         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7797         if (callbacks != null) {
7798             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7799         }
7800     }
7801
7802     @Override
7803     public String getPackageForIntentSender(IIntentSender pendingResult) {
7804         if (!(pendingResult instanceof PendingIntentRecord)) {
7805             return null;
7806         }
7807         try {
7808             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7809             return res.key.packageName;
7810         } catch (ClassCastException e) {
7811         }
7812         return null;
7813     }
7814
7815     @Override
7816     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7817         if (!(sender instanceof PendingIntentRecord)) {
7818             return;
7819         }
7820         synchronized(this) {
7821             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7822         }
7823     }
7824
7825     @Override
7826     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7827             IResultReceiver receiver) {
7828         if (!(sender instanceof PendingIntentRecord)) {
7829             return;
7830         }
7831         synchronized(this) {
7832             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7833         }
7834     }
7835
7836     @Override
7837     public int getUidForIntentSender(IIntentSender sender) {
7838         if (sender instanceof PendingIntentRecord) {
7839             try {
7840                 PendingIntentRecord res = (PendingIntentRecord)sender;
7841                 return res.uid;
7842             } catch (ClassCastException e) {
7843             }
7844         }
7845         return -1;
7846     }
7847
7848     @Override
7849     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7850         if (!(pendingResult instanceof PendingIntentRecord)) {
7851             return false;
7852         }
7853         try {
7854             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7855             if (res.key.allIntents == null) {
7856                 return false;
7857             }
7858             for (int i=0; i<res.key.allIntents.length; i++) {
7859                 Intent intent = res.key.allIntents[i];
7860                 if (intent.getPackage() != null && intent.getComponent() != null) {
7861                     return false;
7862                 }
7863             }
7864             return true;
7865         } catch (ClassCastException e) {
7866         }
7867         return false;
7868     }
7869
7870     @Override
7871     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7872         if (!(pendingResult instanceof PendingIntentRecord)) {
7873             return false;
7874         }
7875         try {
7876             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7877             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7878                 return true;
7879             }
7880             return false;
7881         } catch (ClassCastException e) {
7882         }
7883         return false;
7884     }
7885
7886     @Override
7887     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7888         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7889                 "getIntentForIntentSender()");
7890         if (!(pendingResult instanceof PendingIntentRecord)) {
7891             return null;
7892         }
7893         try {
7894             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7895             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7896         } catch (ClassCastException e) {
7897         }
7898         return null;
7899     }
7900
7901     @Override
7902     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7903         if (!(pendingResult instanceof PendingIntentRecord)) {
7904             return null;
7905         }
7906         try {
7907             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7908             synchronized (this) {
7909                 return getTagForIntentSenderLocked(res, prefix);
7910             }
7911         } catch (ClassCastException e) {
7912         }
7913         return null;
7914     }
7915
7916     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7917         final Intent intent = res.key.requestIntent;
7918         if (intent != null) {
7919             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7920                     || res.lastTagPrefix.equals(prefix))) {
7921                 return res.lastTag;
7922             }
7923             res.lastTagPrefix = prefix;
7924             final StringBuilder sb = new StringBuilder(128);
7925             if (prefix != null) {
7926                 sb.append(prefix);
7927             }
7928             if (intent.getAction() != null) {
7929                 sb.append(intent.getAction());
7930             } else if (intent.getComponent() != null) {
7931                 intent.getComponent().appendShortString(sb);
7932             } else {
7933                 sb.append("?");
7934             }
7935             return res.lastTag = sb.toString();
7936         }
7937         return null;
7938     }
7939
7940     @Override
7941     public void setProcessLimit(int max) {
7942         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7943                 "setProcessLimit()");
7944         synchronized (this) {
7945             mConstants.setOverrideMaxCachedProcesses(max);
7946         }
7947         trimApplications();
7948     }
7949
7950     @Override
7951     public int getProcessLimit() {
7952         synchronized (this) {
7953             return mConstants.getOverrideMaxCachedProcesses();
7954         }
7955     }
7956
7957     void importanceTokenDied(ImportanceToken token) {
7958         synchronized (ActivityManagerService.this) {
7959             synchronized (mPidsSelfLocked) {
7960                 ImportanceToken cur
7961                     = mImportantProcesses.get(token.pid);
7962                 if (cur != token) {
7963                     return;
7964                 }
7965                 mImportantProcesses.remove(token.pid);
7966                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7967                 if (pr == null) {
7968                     return;
7969                 }
7970                 pr.forcingToImportant = null;
7971                 updateProcessForegroundLocked(pr, false, false);
7972             }
7973             updateOomAdjLocked();
7974         }
7975     }
7976
7977     @Override
7978     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7979         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7980                 "setProcessImportant()");
7981         synchronized(this) {
7982             boolean changed = false;
7983
7984             synchronized (mPidsSelfLocked) {
7985                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7986                 if (pr == null && isForeground) {
7987                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7988                     return;
7989                 }
7990                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7991                 if (oldToken != null) {
7992                     oldToken.token.unlinkToDeath(oldToken, 0);
7993                     mImportantProcesses.remove(pid);
7994                     if (pr != null) {
7995                         pr.forcingToImportant = null;
7996                     }
7997                     changed = true;
7998                 }
7999                 if (isForeground && token != null) {
8000                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8001                         @Override
8002                         public void binderDied() {
8003                             importanceTokenDied(this);
8004                         }
8005                     };
8006                     try {
8007                         token.linkToDeath(newToken, 0);
8008                         mImportantProcesses.put(pid, newToken);
8009                         pr.forcingToImportant = newToken;
8010                         changed = true;
8011                     } catch (RemoteException e) {
8012                         // If the process died while doing this, we will later
8013                         // do the cleanup with the process death link.
8014                     }
8015                 }
8016             }
8017
8018             if (changed) {
8019                 updateOomAdjLocked();
8020             }
8021         }
8022     }
8023
8024     @Override
8025     public boolean isAppForeground(int uid) throws RemoteException {
8026         synchronized (this) {
8027             UidRecord uidRec = mActiveUids.get(uid);
8028             if (uidRec == null || uidRec.idle) {
8029                 return false;
8030             }
8031             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8032         }
8033     }
8034
8035     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8036     // be guarded by permission checking.
8037     int getUidState(int uid) {
8038         synchronized (this) {
8039             return getUidStateLocked(uid);
8040         }
8041     }
8042
8043     int getUidStateLocked(int uid) {
8044         UidRecord uidRec = mActiveUids.get(uid);
8045         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8046     }
8047
8048     @Override
8049     public boolean isInMultiWindowMode(IBinder token) {
8050         final long origId = Binder.clearCallingIdentity();
8051         try {
8052             synchronized(this) {
8053                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8054                 if (r == null) {
8055                     return false;
8056                 }
8057                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8058                 return !r.getTask().mFullscreen;
8059             }
8060         } finally {
8061             Binder.restoreCallingIdentity(origId);
8062         }
8063     }
8064
8065     @Override
8066     public boolean isInPictureInPictureMode(IBinder token) {
8067         final long origId = Binder.clearCallingIdentity();
8068         try {
8069             synchronized(this) {
8070                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8071             }
8072         } finally {
8073             Binder.restoreCallingIdentity(origId);
8074         }
8075     }
8076
8077     private boolean isInPictureInPictureMode(ActivityRecord r) {
8078         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8079                 r.getStack().isInStackLocked(r) == null) {
8080             return false;
8081         }
8082
8083         // If we are animating to fullscreen then we have already dispatched the PIP mode
8084         // changed, so we should reflect that check here as well.
8085         final PinnedActivityStack stack = r.getStack();
8086         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8087         return !windowController.isAnimatingBoundsToFullscreen();
8088     }
8089
8090     @Override
8091     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8092         final long origId = Binder.clearCallingIdentity();
8093         try {
8094             synchronized(this) {
8095                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8096                         "enterPictureInPictureMode", token, params);
8097
8098                 // If the activity is already in picture in picture mode, then just return early
8099                 if (isInPictureInPictureMode(r)) {
8100                     return true;
8101                 }
8102
8103                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8104                 // point, if it is
8105                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8106                         false /* beforeStopping */)) {
8107                     return false;
8108                 }
8109
8110                 final Runnable enterPipRunnable = () -> {
8111                     // Only update the saved args from the args that are set
8112                     r.pictureInPictureArgs.copyOnlySet(params);
8113                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8114                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8115                     // Adjust the source bounds by the insets for the transition down
8116                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8117                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8118                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8119                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8120                     stack.setPictureInPictureAspectRatio(aspectRatio);
8121                     stack.setPictureInPictureActions(actions);
8122
8123                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8124                             r.supportsEnterPipOnTaskSwitch);
8125                     logPictureInPictureArgs(params);
8126                 };
8127
8128                 if (isKeyguardLocked()) {
8129                     // If the keyguard is showing or occluded, then try and dismiss it before
8130                     // entering picture-in-picture (this will prompt the user to authenticate if the
8131                     // device is currently locked).
8132                     try {
8133                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8134                             @Override
8135                             public void onDismissError() throws RemoteException {
8136                                 // Do nothing
8137                             }
8138
8139                             @Override
8140                             public void onDismissSucceeded() throws RemoteException {
8141                                 mHandler.post(enterPipRunnable);
8142                             }
8143
8144                             @Override
8145                             public void onDismissCancelled() throws RemoteException {
8146                                 // Do nothing
8147                             }
8148                         });
8149                     } catch (RemoteException e) {
8150                         // Local call
8151                     }
8152                 } else {
8153                     // Enter picture in picture immediately otherwise
8154                     enterPipRunnable.run();
8155                 }
8156                 return true;
8157             }
8158         } finally {
8159             Binder.restoreCallingIdentity(origId);
8160         }
8161     }
8162
8163     @Override
8164     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8165         final long origId = Binder.clearCallingIdentity();
8166         try {
8167             synchronized(this) {
8168                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8169                         "setPictureInPictureParams", token, params);
8170
8171                 // Only update the saved args from the args that are set
8172                 r.pictureInPictureArgs.copyOnlySet(params);
8173                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8174                     // If the activity is already in picture-in-picture, update the pinned stack now
8175                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8176                     // be used the next time the activity enters PiP
8177                     final PinnedActivityStack stack = r.getStack();
8178                     if (!stack.isAnimatingBoundsToFullscreen()) {
8179                         stack.setPictureInPictureAspectRatio(
8180                                 r.pictureInPictureArgs.getAspectRatio());
8181                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8182                     }
8183                 }
8184                 logPictureInPictureArgs(params);
8185             }
8186         } finally {
8187             Binder.restoreCallingIdentity(origId);
8188         }
8189     }
8190
8191     @Override
8192     public int getMaxNumPictureInPictureActions(IBinder token) {
8193         // Currently, this is a static constant, but later, we may change this to be dependent on
8194         // the context of the activity
8195         return 3;
8196     }
8197
8198     private void logPictureInPictureArgs(PictureInPictureParams params) {
8199         if (params.hasSetActions()) {
8200             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8201                     params.getActions().size());
8202         }
8203         if (params.hasSetAspectRatio()) {
8204             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8205             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8206             MetricsLogger.action(lm);
8207         }
8208     }
8209
8210     /**
8211      * Checks the state of the system and the activity associated with the given {@param token} to
8212      * verify that picture-in-picture is supported for that activity.
8213      *
8214      * @return the activity record for the given {@param token} if all the checks pass.
8215      */
8216     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8217             IBinder token, PictureInPictureParams params) {
8218         if (!mSupportsPictureInPicture) {
8219             throw new IllegalStateException(caller
8220                     + ": Device doesn't support picture-in-picture mode.");
8221         }
8222
8223         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8224         if (r == null) {
8225             throw new IllegalStateException(caller
8226                     + ": Can't find activity for token=" + token);
8227         }
8228
8229         if (!r.supportsPictureInPicture()) {
8230             throw new IllegalStateException(caller
8231                     + ": Current activity does not support picture-in-picture.");
8232         }
8233
8234         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8235             throw new IllegalStateException(caller
8236                     + ": Activities on the home, assistant, or recents stack not supported");
8237         }
8238
8239         if (params.hasSetAspectRatio()
8240                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8241                         params.getAspectRatio())) {
8242             final float minAspectRatio = mContext.getResources().getFloat(
8243                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8244             final float maxAspectRatio = mContext.getResources().getFloat(
8245                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8246             throw new IllegalArgumentException(String.format(caller
8247                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8248                             minAspectRatio, maxAspectRatio));
8249         }
8250
8251         // Truncate the number of actions if necessary
8252         params.truncateActions(getMaxNumPictureInPictureActions(token));
8253
8254         return r;
8255     }
8256
8257     // =========================================================
8258     // PROCESS INFO
8259     // =========================================================
8260
8261     static class ProcessInfoService extends IProcessInfoService.Stub {
8262         final ActivityManagerService mActivityManagerService;
8263         ProcessInfoService(ActivityManagerService activityManagerService) {
8264             mActivityManagerService = activityManagerService;
8265         }
8266
8267         @Override
8268         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8269             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8270                     /*in*/ pids, /*out*/ states, null);
8271         }
8272
8273         @Override
8274         public void getProcessStatesAndOomScoresFromPids(
8275                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8276             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8277                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8278         }
8279     }
8280
8281     /**
8282      * For each PID in the given input array, write the current process state
8283      * for that process into the states array, or -1 to indicate that no
8284      * process with the given PID exists. If scores array is provided, write
8285      * the oom score for the process into the scores array, with INVALID_ADJ
8286      * indicating the PID doesn't exist.
8287      */
8288     public void getProcessStatesAndOomScoresForPIDs(
8289             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8290         if (scores != null) {
8291             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8292                     "getProcessStatesAndOomScoresForPIDs()");
8293         }
8294
8295         if (pids == null) {
8296             throw new NullPointerException("pids");
8297         } else if (states == null) {
8298             throw new NullPointerException("states");
8299         } else if (pids.length != states.length) {
8300             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8301         } else if (scores != null && pids.length != scores.length) {
8302             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8303         }
8304
8305         synchronized (mPidsSelfLocked) {
8306             for (int i = 0; i < pids.length; i++) {
8307                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8308                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8309                         pr.curProcState;
8310                 if (scores != null) {
8311                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8312                 }
8313             }
8314         }
8315     }
8316
8317     // =========================================================
8318     // PERMISSIONS
8319     // =========================================================
8320
8321     static class PermissionController extends IPermissionController.Stub {
8322         ActivityManagerService mActivityManagerService;
8323         PermissionController(ActivityManagerService activityManagerService) {
8324             mActivityManagerService = activityManagerService;
8325         }
8326
8327         @Override
8328         public boolean checkPermission(String permission, int pid, int uid) {
8329             return mActivityManagerService.checkPermission(permission, pid,
8330                     uid) == PackageManager.PERMISSION_GRANTED;
8331         }
8332
8333         @Override
8334         public String[] getPackagesForUid(int uid) {
8335             return mActivityManagerService.mContext.getPackageManager()
8336                     .getPackagesForUid(uid);
8337         }
8338
8339         @Override
8340         public boolean isRuntimePermission(String permission) {
8341             try {
8342                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8343                         .getPermissionInfo(permission, 0);
8344                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8345                         == PermissionInfo.PROTECTION_DANGEROUS;
8346             } catch (NameNotFoundException nnfe) {
8347                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8348             }
8349             return false;
8350         }
8351     }
8352
8353     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8354         @Override
8355         public int checkComponentPermission(String permission, int pid, int uid,
8356                 int owningUid, boolean exported) {
8357             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8358                     owningUid, exported);
8359         }
8360
8361         @Override
8362         public Object getAMSLock() {
8363             return ActivityManagerService.this;
8364         }
8365     }
8366
8367     /**
8368      * This can be called with or without the global lock held.
8369      */
8370     int checkComponentPermission(String permission, int pid, int uid,
8371             int owningUid, boolean exported) {
8372         if (pid == MY_PID) {
8373             return PackageManager.PERMISSION_GRANTED;
8374         }
8375         return ActivityManager.checkComponentPermission(permission, uid,
8376                 owningUid, exported);
8377     }
8378
8379     /**
8380      * As the only public entry point for permissions checking, this method
8381      * can enforce the semantic that requesting a check on a null global
8382      * permission is automatically denied.  (Internally a null permission
8383      * string is used when calling {@link #checkComponentPermission} in cases
8384      * when only uid-based security is needed.)
8385      *
8386      * This can be called with or without the global lock held.
8387      */
8388     @Override
8389     public int checkPermission(String permission, int pid, int uid) {
8390         if (permission == null) {
8391             return PackageManager.PERMISSION_DENIED;
8392         }
8393         return checkComponentPermission(permission, pid, uid, -1, true);
8394     }
8395
8396     @Override
8397     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8398         if (permission == null) {
8399             return PackageManager.PERMISSION_DENIED;
8400         }
8401
8402         // We might be performing an operation on behalf of an indirect binder
8403         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8404         // client identity accordingly before proceeding.
8405         Identity tlsIdentity = sCallerIdentity.get();
8406         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8407             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8408                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8409             uid = tlsIdentity.uid;
8410             pid = tlsIdentity.pid;
8411         }
8412
8413         return checkComponentPermission(permission, pid, uid, -1, true);
8414     }
8415
8416     /**
8417      * Binder IPC calls go through the public entry point.
8418      * This can be called with or without the global lock held.
8419      */
8420     int checkCallingPermission(String permission) {
8421         return checkPermission(permission,
8422                 Binder.getCallingPid(),
8423                 UserHandle.getAppId(Binder.getCallingUid()));
8424     }
8425
8426     /**
8427      * This can be called with or without the global lock held.
8428      */
8429     void enforceCallingPermission(String permission, String func) {
8430         if (checkCallingPermission(permission)
8431                 == PackageManager.PERMISSION_GRANTED) {
8432             return;
8433         }
8434
8435         String msg = "Permission Denial: " + func + " from pid="
8436                 + Binder.getCallingPid()
8437                 + ", uid=" + Binder.getCallingUid()
8438                 + " requires " + permission;
8439         Slog.w(TAG, msg);
8440         throw new SecurityException(msg);
8441     }
8442
8443     /**
8444      * Determine if UID is holding permissions required to access {@link Uri} in
8445      * the given {@link ProviderInfo}. Final permission checking is always done
8446      * in {@link ContentProvider}.
8447      */
8448     private final boolean checkHoldingPermissionsLocked(
8449             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8450         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8451                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8452         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8453             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8454                     != PERMISSION_GRANTED) {
8455                 return false;
8456             }
8457         }
8458         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8459     }
8460
8461     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8462             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8463         if (pi.applicationInfo.uid == uid) {
8464             return true;
8465         } else if (!pi.exported) {
8466             return false;
8467         }
8468
8469         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8470         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8471         try {
8472             // check if target holds top-level <provider> permissions
8473             if (!readMet && pi.readPermission != null && considerUidPermissions
8474                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8475                 readMet = true;
8476             }
8477             if (!writeMet && pi.writePermission != null && considerUidPermissions
8478                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8479                 writeMet = true;
8480             }
8481
8482             // track if unprotected read/write is allowed; any denied
8483             // <path-permission> below removes this ability
8484             boolean allowDefaultRead = pi.readPermission == null;
8485             boolean allowDefaultWrite = pi.writePermission == null;
8486
8487             // check if target holds any <path-permission> that match uri
8488             final PathPermission[] pps = pi.pathPermissions;
8489             if (pps != null) {
8490                 final String path = grantUri.uri.getPath();
8491                 int i = pps.length;
8492                 while (i > 0 && (!readMet || !writeMet)) {
8493                     i--;
8494                     PathPermission pp = pps[i];
8495                     if (pp.match(path)) {
8496                         if (!readMet) {
8497                             final String pprperm = pp.getReadPermission();
8498                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8499                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8500                                     + ": match=" + pp.match(path)
8501                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8502                             if (pprperm != null) {
8503                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8504                                         == PERMISSION_GRANTED) {
8505                                     readMet = true;
8506                                 } else {
8507                                     allowDefaultRead = false;
8508                                 }
8509                             }
8510                         }
8511                         if (!writeMet) {
8512                             final String ppwperm = pp.getWritePermission();
8513                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8514                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8515                                     + ": match=" + pp.match(path)
8516                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8517                             if (ppwperm != null) {
8518                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8519                                         == PERMISSION_GRANTED) {
8520                                     writeMet = true;
8521                                 } else {
8522                                     allowDefaultWrite = false;
8523                                 }
8524                             }
8525                         }
8526                     }
8527                 }
8528             }
8529
8530             // grant unprotected <provider> read/write, if not blocked by
8531             // <path-permission> above
8532             if (allowDefaultRead) readMet = true;
8533             if (allowDefaultWrite) writeMet = true;
8534
8535         } catch (RemoteException e) {
8536             return false;
8537         }
8538
8539         return readMet && writeMet;
8540     }
8541
8542     public boolean isAppStartModeDisabled(int uid, String packageName) {
8543         synchronized (this) {
8544             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8545                     == ActivityManager.APP_START_MODE_DISABLED;
8546         }
8547     }
8548
8549     // Unified app-op and target sdk check
8550     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8551         // Apps that target O+ are always subject to background check
8552         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8553             if (DEBUG_BACKGROUND_CHECK) {
8554                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8555             }
8556             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8557         }
8558         // ...and legacy apps get an AppOp check
8559         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8560                 uid, packageName);
8561         if (DEBUG_BACKGROUND_CHECK) {
8562             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8563         }
8564         switch (appop) {
8565             case AppOpsManager.MODE_ALLOWED:
8566                 return ActivityManager.APP_START_MODE_NORMAL;
8567             case AppOpsManager.MODE_IGNORED:
8568                 return ActivityManager.APP_START_MODE_DELAYED;
8569             default:
8570                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8571         }
8572     }
8573
8574     // Service launch is available to apps with run-in-background exemptions but
8575     // some other background operations are not.  If we're doing a check
8576     // of service-launch policy, allow those callers to proceed unrestricted.
8577     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8578         // Persistent app?
8579         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8580             if (DEBUG_BACKGROUND_CHECK) {
8581                 Slog.i(TAG, "App " + uid + "/" + packageName
8582                         + " is persistent; not restricted in background");
8583             }
8584             return ActivityManager.APP_START_MODE_NORMAL;
8585         }
8586
8587         // Non-persistent but background whitelisted?
8588         if (uidOnBackgroundWhitelist(uid)) {
8589             if (DEBUG_BACKGROUND_CHECK) {
8590                 Slog.i(TAG, "App " + uid + "/" + packageName
8591                         + " on background whitelist; not restricted in background");
8592             }
8593             return ActivityManager.APP_START_MODE_NORMAL;
8594         }
8595
8596         // Is this app on the battery whitelist?
8597         if (isOnDeviceIdleWhitelistLocked(uid)) {
8598             if (DEBUG_BACKGROUND_CHECK) {
8599                 Slog.i(TAG, "App " + uid + "/" + packageName
8600                         + " on idle whitelist; not restricted in background");
8601             }
8602             return ActivityManager.APP_START_MODE_NORMAL;
8603         }
8604
8605         // None of the service-policy criteria apply, so we apply the common criteria
8606         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8607     }
8608
8609     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8610             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8611         UidRecord uidRec = mActiveUids.get(uid);
8612         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8613                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8614                 + (uidRec != null ? uidRec.idle : false));
8615         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8616             boolean ephemeral;
8617             if (uidRec == null) {
8618                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8619                         UserHandle.getUserId(uid), packageName);
8620             } else {
8621                 ephemeral = uidRec.ephemeral;
8622             }
8623
8624             if (ephemeral) {
8625                 // We are hard-core about ephemeral apps not running in the background.
8626                 return ActivityManager.APP_START_MODE_DISABLED;
8627             } else {
8628                 if (disabledOnly) {
8629                     // The caller is only interested in whether app starts are completely
8630                     // disabled for the given package (that is, it is an instant app).  So
8631                     // we don't need to go further, which is all just seeing if we should
8632                     // apply a "delayed" mode for a regular app.
8633                     return ActivityManager.APP_START_MODE_NORMAL;
8634                 }
8635                 final int startMode = (alwaysRestrict)
8636                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8637                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8638                                 packageTargetSdk);
8639                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8640                         + " pkg=" + packageName + " startMode=" + startMode
8641                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8642                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8643                     // This is an old app that has been forced into a "compatible as possible"
8644                     // mode of background check.  To increase compatibility, we will allow other
8645                     // foreground apps to cause its services to start.
8646                     if (callingPid >= 0) {
8647                         ProcessRecord proc;
8648                         synchronized (mPidsSelfLocked) {
8649                             proc = mPidsSelfLocked.get(callingPid);
8650                         }
8651                         if (proc != null &&
8652                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8653                             // Whoever is instigating this is in the foreground, so we will allow it
8654                             // to go through.
8655                             return ActivityManager.APP_START_MODE_NORMAL;
8656                         }
8657                     }
8658                 }
8659                 return startMode;
8660             }
8661         }
8662         return ActivityManager.APP_START_MODE_NORMAL;
8663     }
8664
8665     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8666         final int appId = UserHandle.getAppId(uid);
8667         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8668                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8669                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8670     }
8671
8672     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8673         ProviderInfo pi = null;
8674         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8675         if (cpr != null) {
8676             pi = cpr.info;
8677         } else {
8678             try {
8679                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8680                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8681                         userHandle);
8682             } catch (RemoteException ex) {
8683             }
8684         }
8685         return pi;
8686     }
8687
8688     void grantEphemeralAccessLocked(int userId, Intent intent,
8689             int targetAppId, int ephemeralAppId) {
8690         getPackageManagerInternalLocked().
8691                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8692     }
8693
8694     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8695         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8696         if (targetUris != null) {
8697             return targetUris.get(grantUri);
8698         }
8699         return null;
8700     }
8701
8702     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8703             String targetPkg, int targetUid, GrantUri grantUri) {
8704         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8705         if (targetUris == null) {
8706             targetUris = Maps.newArrayMap();
8707             mGrantedUriPermissions.put(targetUid, targetUris);
8708         }
8709
8710         UriPermission perm = targetUris.get(grantUri);
8711         if (perm == null) {
8712             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8713             targetUris.put(grantUri, perm);
8714         }
8715
8716         return perm;
8717     }
8718
8719     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8720             final int modeFlags) {
8721         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8722         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8723                 : UriPermission.STRENGTH_OWNED;
8724
8725         // Root gets to do everything.
8726         if (uid == 0) {
8727             return true;
8728         }
8729
8730         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8731         if (perms == null) return false;
8732
8733         // First look for exact match
8734         final UriPermission exactPerm = perms.get(grantUri);
8735         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8736             return true;
8737         }
8738
8739         // No exact match, look for prefixes
8740         final int N = perms.size();
8741         for (int i = 0; i < N; i++) {
8742             final UriPermission perm = perms.valueAt(i);
8743             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8744                     && perm.getStrength(modeFlags) >= minStrength) {
8745                 return true;
8746             }
8747         }
8748
8749         return false;
8750     }
8751
8752     /**
8753      * @param uri This uri must NOT contain an embedded userId.
8754      * @param userId The userId in which the uri is to be resolved.
8755      */
8756     @Override
8757     public int checkUriPermission(Uri uri, int pid, int uid,
8758             final int modeFlags, int userId, IBinder callerToken) {
8759         enforceNotIsolatedCaller("checkUriPermission");
8760
8761         // Another redirected-binder-call permissions check as in
8762         // {@link checkPermissionWithToken}.
8763         Identity tlsIdentity = sCallerIdentity.get();
8764         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8765             uid = tlsIdentity.uid;
8766             pid = tlsIdentity.pid;
8767         }
8768
8769         // Our own process gets to do everything.
8770         if (pid == MY_PID) {
8771             return PackageManager.PERMISSION_GRANTED;
8772         }
8773         synchronized (this) {
8774             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8775                     ? PackageManager.PERMISSION_GRANTED
8776                     : PackageManager.PERMISSION_DENIED;
8777         }
8778     }
8779
8780     /**
8781      * Check if the targetPkg can be granted permission to access uri by
8782      * the callingUid using the given modeFlags.  Throws a security exception
8783      * if callingUid is not allowed to do this.  Returns the uid of the target
8784      * if the URI permission grant should be performed; returns -1 if it is not
8785      * needed (for example targetPkg already has permission to access the URI).
8786      * If you already know the uid of the target, you can supply it in
8787      * lastTargetUid else set that to -1.
8788      */
8789     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8790             final int modeFlags, int lastTargetUid) {
8791         if (!Intent.isAccessUriMode(modeFlags)) {
8792             return -1;
8793         }
8794
8795         if (targetPkg != null) {
8796             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8797                     "Checking grant " + targetPkg + " permission to " + grantUri);
8798         }
8799
8800         final IPackageManager pm = AppGlobals.getPackageManager();
8801
8802         // If this is not a content: uri, we can't do anything with it.
8803         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8804             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8805                     "Can't grant URI permission for non-content URI: " + grantUri);
8806             return -1;
8807         }
8808
8809         // Bail early if system is trying to hand out permissions directly; it
8810         // must always grant permissions on behalf of someone explicit.
8811         final int callingAppId = UserHandle.getAppId(callingUid);
8812         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8813             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8814                 // Exempted authority for cropping user photos in Settings app
8815             } else {
8816                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8817                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8818                 return -1;
8819             }
8820         }
8821
8822         final String authority = grantUri.uri.getAuthority();
8823         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8824                 MATCH_DEBUG_TRIAGED_MISSING);
8825         if (pi == null) {
8826             Slog.w(TAG, "No content provider found for permission check: " +
8827                     grantUri.uri.toSafeString());
8828             return -1;
8829         }
8830
8831         int targetUid = lastTargetUid;
8832         if (targetUid < 0 && targetPkg != null) {
8833             try {
8834                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8835                         UserHandle.getUserId(callingUid));
8836                 if (targetUid < 0) {
8837                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8838                             "Can't grant URI permission no uid for: " + targetPkg);
8839                     return -1;
8840                 }
8841             } catch (RemoteException ex) {
8842                 return -1;
8843             }
8844         }
8845
8846         // If we're extending a persistable grant, then we always need to create
8847         // the grant data structure so that take/release APIs work
8848         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8849             return targetUid;
8850         }
8851
8852         if (targetUid >= 0) {
8853             // First...  does the target actually need this permission?
8854             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8855                 // No need to grant the target this permission.
8856                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8857                         "Target " + targetPkg + " already has full permission to " + grantUri);
8858                 return -1;
8859             }
8860         } else {
8861             // First...  there is no target package, so can anyone access it?
8862             boolean allowed = pi.exported;
8863             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8864                 if (pi.readPermission != null) {
8865                     allowed = false;
8866                 }
8867             }
8868             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8869                 if (pi.writePermission != null) {
8870                     allowed = false;
8871                 }
8872             }
8873             if (allowed) {
8874                 return -1;
8875             }
8876         }
8877
8878         /* There is a special cross user grant if:
8879          * - The target is on another user.
8880          * - Apps on the current user can access the uri without any uid permissions.
8881          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8882          * grant uri permissions.
8883          */
8884         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8885                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8886                 modeFlags, false /*without considering the uid permissions*/);
8887
8888         // Second...  is the provider allowing granting of URI permissions?
8889         if (!specialCrossUserGrant) {
8890             if (!pi.grantUriPermissions) {
8891                 throw new SecurityException("Provider " + pi.packageName
8892                         + "/" + pi.name
8893                         + " does not allow granting of Uri permissions (uri "
8894                         + grantUri + ")");
8895             }
8896             if (pi.uriPermissionPatterns != null) {
8897                 final int N = pi.uriPermissionPatterns.length;
8898                 boolean allowed = false;
8899                 for (int i=0; i<N; i++) {
8900                     if (pi.uriPermissionPatterns[i] != null
8901                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8902                         allowed = true;
8903                         break;
8904                     }
8905                 }
8906                 if (!allowed) {
8907                     throw new SecurityException("Provider " + pi.packageName
8908                             + "/" + pi.name
8909                             + " does not allow granting of permission to path of Uri "
8910                             + grantUri);
8911                 }
8912             }
8913         }
8914
8915         // Third...  does the caller itself have permission to access
8916         // this uri?
8917         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8918             // Require they hold a strong enough Uri permission
8919             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8920                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8921                     throw new SecurityException(
8922                             "UID " + callingUid + " does not have permission to " + grantUri
8923                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8924                                     + "or related APIs");
8925                 } else {
8926                     throw new SecurityException(
8927                             "UID " + callingUid + " does not have permission to " + grantUri);
8928                 }
8929             }
8930         }
8931         return targetUid;
8932     }
8933
8934     /**
8935      * @param uri This uri must NOT contain an embedded userId.
8936      * @param userId The userId in which the uri is to be resolved.
8937      */
8938     @Override
8939     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8940             final int modeFlags, int userId) {
8941         enforceNotIsolatedCaller("checkGrantUriPermission");
8942         synchronized(this) {
8943             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8944                     new GrantUri(userId, uri, false), modeFlags, -1);
8945         }
8946     }
8947
8948     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8949             final int modeFlags, UriPermissionOwner owner) {
8950         if (!Intent.isAccessUriMode(modeFlags)) {
8951             return;
8952         }
8953
8954         // So here we are: the caller has the assumed permission
8955         // to the uri, and the target doesn't.  Let's now give this to
8956         // the target.
8957
8958         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8959                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8960
8961         final String authority = grantUri.uri.getAuthority();
8962         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8963                 MATCH_DEBUG_TRIAGED_MISSING);
8964         if (pi == null) {
8965             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8966             return;
8967         }
8968
8969         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8970             grantUri.prefix = true;
8971         }
8972         final UriPermission perm = findOrCreateUriPermissionLocked(
8973                 pi.packageName, targetPkg, targetUid, grantUri);
8974         perm.grantModes(modeFlags, owner);
8975     }
8976
8977     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8978             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8979         if (targetPkg == null) {
8980             throw new NullPointerException("targetPkg");
8981         }
8982         int targetUid;
8983         final IPackageManager pm = AppGlobals.getPackageManager();
8984         try {
8985             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8986         } catch (RemoteException ex) {
8987             return;
8988         }
8989
8990         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8991                 targetUid);
8992         if (targetUid < 0) {
8993             return;
8994         }
8995
8996         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8997                 owner);
8998     }
8999
9000     static class NeededUriGrants extends ArrayList<GrantUri> {
9001         final String targetPkg;
9002         final int targetUid;
9003         final int flags;
9004
9005         NeededUriGrants(String targetPkg, int targetUid, int flags) {
9006             this.targetPkg = targetPkg;
9007             this.targetUid = targetUid;
9008             this.flags = flags;
9009         }
9010     }
9011
9012     /**
9013      * Like checkGrantUriPermissionLocked, but takes an Intent.
9014      */
9015     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9016             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9017         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9018                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9019                 + " clip=" + (intent != null ? intent.getClipData() : null)
9020                 + " from " + intent + "; flags=0x"
9021                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9022
9023         if (targetPkg == null) {
9024             throw new NullPointerException("targetPkg");
9025         }
9026
9027         if (intent == null) {
9028             return null;
9029         }
9030         Uri data = intent.getData();
9031         ClipData clip = intent.getClipData();
9032         if (data == null && clip == null) {
9033             return null;
9034         }
9035         // Default userId for uris in the intent (if they don't specify it themselves)
9036         int contentUserHint = intent.getContentUserHint();
9037         if (contentUserHint == UserHandle.USER_CURRENT) {
9038             contentUserHint = UserHandle.getUserId(callingUid);
9039         }
9040         final IPackageManager pm = AppGlobals.getPackageManager();
9041         int targetUid;
9042         if (needed != null) {
9043             targetUid = needed.targetUid;
9044         } else {
9045             try {
9046                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9047                         targetUserId);
9048             } catch (RemoteException ex) {
9049                 return null;
9050             }
9051             if (targetUid < 0) {
9052                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9053                         "Can't grant URI permission no uid for: " + targetPkg
9054                         + " on user " + targetUserId);
9055                 return null;
9056             }
9057         }
9058         if (data != null) {
9059             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9060             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9061                     targetUid);
9062             if (targetUid > 0) {
9063                 if (needed == null) {
9064                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9065                 }
9066                 needed.add(grantUri);
9067             }
9068         }
9069         if (clip != null) {
9070             for (int i=0; i<clip.getItemCount(); i++) {
9071                 Uri uri = clip.getItemAt(i).getUri();
9072                 if (uri != null) {
9073                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9074                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9075                             targetUid);
9076                     if (targetUid > 0) {
9077                         if (needed == null) {
9078                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9079                         }
9080                         needed.add(grantUri);
9081                     }
9082                 } else {
9083                     Intent clipIntent = clip.getItemAt(i).getIntent();
9084                     if (clipIntent != null) {
9085                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9086                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9087                         if (newNeeded != null) {
9088                             needed = newNeeded;
9089                         }
9090                     }
9091                 }
9092             }
9093         }
9094
9095         return needed;
9096     }
9097
9098     /**
9099      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9100      */
9101     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9102             UriPermissionOwner owner) {
9103         if (needed != null) {
9104             for (int i=0; i<needed.size(); i++) {
9105                 GrantUri grantUri = needed.get(i);
9106                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9107                         grantUri, needed.flags, owner);
9108             }
9109         }
9110     }
9111
9112     void grantUriPermissionFromIntentLocked(int callingUid,
9113             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9114         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9115                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9116         if (needed == null) {
9117             return;
9118         }
9119
9120         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9121     }
9122
9123     /**
9124      * @param uri This uri must NOT contain an embedded userId.
9125      * @param userId The userId in which the uri is to be resolved.
9126      */
9127     @Override
9128     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9129             final int modeFlags, int userId) {
9130         enforceNotIsolatedCaller("grantUriPermission");
9131         GrantUri grantUri = new GrantUri(userId, uri, false);
9132         synchronized(this) {
9133             final ProcessRecord r = getRecordForAppLocked(caller);
9134             if (r == null) {
9135                 throw new SecurityException("Unable to find app for caller "
9136                         + caller
9137                         + " when granting permission to uri " + grantUri);
9138             }
9139             if (targetPkg == null) {
9140                 throw new IllegalArgumentException("null target");
9141             }
9142             if (grantUri == null) {
9143                 throw new IllegalArgumentException("null uri");
9144             }
9145
9146             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9147                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9148                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9149                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9150
9151             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9152                     UserHandle.getUserId(r.uid));
9153         }
9154     }
9155
9156     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9157         if (perm.modeFlags == 0) {
9158             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9159                     perm.targetUid);
9160             if (perms != null) {
9161                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9162                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9163
9164                 perms.remove(perm.uri);
9165                 if (perms.isEmpty()) {
9166                     mGrantedUriPermissions.remove(perm.targetUid);
9167                 }
9168             }
9169         }
9170     }
9171
9172     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9173             final int modeFlags) {
9174         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9175                 "Revoking all granted permissions to " + grantUri);
9176
9177         final IPackageManager pm = AppGlobals.getPackageManager();
9178         final String authority = grantUri.uri.getAuthority();
9179         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9180                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9181         if (pi == null) {
9182             Slog.w(TAG, "No content provider found for permission revoke: "
9183                     + grantUri.toSafeString());
9184             return;
9185         }
9186
9187         // Does the caller have this permission on the URI?
9188         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9189             // If they don't have direct access to the URI, then revoke any
9190             // ownerless URI permissions that have been granted to them.
9191             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9192             if (perms != null) {
9193                 boolean persistChanged = false;
9194                 for (int i = perms.size()-1; i >= 0; i--) {
9195                     final UriPermission perm = perms.valueAt(i);
9196                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9197                         continue;
9198                     }
9199                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9200                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9201                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9202                                 "Revoking non-owned " + perm.targetUid
9203                                 + " permission to " + perm.uri);
9204                         persistChanged |= perm.revokeModes(
9205                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9206                         if (perm.modeFlags == 0) {
9207                             perms.removeAt(i);
9208                         }
9209                     }
9210                 }
9211                 if (perms.isEmpty()) {
9212                     mGrantedUriPermissions.remove(callingUid);
9213                 }
9214                 if (persistChanged) {
9215                     schedulePersistUriGrants();
9216                 }
9217             }
9218             return;
9219         }
9220
9221         boolean persistChanged = false;
9222
9223         // Go through all of the permissions and remove any that match.
9224         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9225             final int targetUid = mGrantedUriPermissions.keyAt(i);
9226             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9227
9228             for (int j = perms.size()-1; j >= 0; j--) {
9229                 final UriPermission perm = perms.valueAt(j);
9230                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9231                     continue;
9232                 }
9233                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9234                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9235                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9236                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9237                     persistChanged |= perm.revokeModes(
9238                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9239                             targetPackage == null);
9240                     if (perm.modeFlags == 0) {
9241                         perms.removeAt(j);
9242                     }
9243                 }
9244             }
9245
9246             if (perms.isEmpty()) {
9247                 mGrantedUriPermissions.removeAt(i);
9248             }
9249         }
9250
9251         if (persistChanged) {
9252             schedulePersistUriGrants();
9253         }
9254     }
9255
9256     /**
9257      * @param uri This uri must NOT contain an embedded userId.
9258      * @param userId The userId in which the uri is to be resolved.
9259      */
9260     @Override
9261     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9262             final int modeFlags, int userId) {
9263         enforceNotIsolatedCaller("revokeUriPermission");
9264         synchronized(this) {
9265             final ProcessRecord r = getRecordForAppLocked(caller);
9266             if (r == null) {
9267                 throw new SecurityException("Unable to find app for caller "
9268                         + caller
9269                         + " when revoking permission to uri " + uri);
9270             }
9271             if (uri == null) {
9272                 Slog.w(TAG, "revokeUriPermission: null uri");
9273                 return;
9274             }
9275
9276             if (!Intent.isAccessUriMode(modeFlags)) {
9277                 return;
9278             }
9279
9280             final String authority = uri.getAuthority();
9281             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9282                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9283             if (pi == null) {
9284                 Slog.w(TAG, "No content provider found for permission revoke: "
9285                         + uri.toSafeString());
9286                 return;
9287             }
9288
9289             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9290                     modeFlags);
9291         }
9292     }
9293
9294     /**
9295      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9296      * given package.
9297      *
9298      * @param packageName Package name to match, or {@code null} to apply to all
9299      *            packages.
9300      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9301      *            to all users.
9302      * @param persistable If persistable grants should be removed.
9303      */
9304     private void removeUriPermissionsForPackageLocked(
9305             String packageName, int userHandle, boolean persistable) {
9306         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9307             throw new IllegalArgumentException("Must narrow by either package or user");
9308         }
9309
9310         boolean persistChanged = false;
9311
9312         int N = mGrantedUriPermissions.size();
9313         for (int i = 0; i < N; i++) {
9314             final int targetUid = mGrantedUriPermissions.keyAt(i);
9315             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9316
9317             // Only inspect grants matching user
9318             if (userHandle == UserHandle.USER_ALL
9319                     || userHandle == UserHandle.getUserId(targetUid)) {
9320                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9321                     final UriPermission perm = it.next();
9322
9323                     // Only inspect grants matching package
9324                     if (packageName == null || perm.sourcePkg.equals(packageName)
9325                             || perm.targetPkg.equals(packageName)) {
9326                         // Hacky solution as part of fixing a security bug; ignore
9327                         // grants associated with DownloadManager so we don't have
9328                         // to immediately launch it to regrant the permissions
9329                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9330                                 && !persistable) continue;
9331
9332                         persistChanged |= perm.revokeModes(persistable
9333                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9334
9335                         // Only remove when no modes remain; any persisted grants
9336                         // will keep this alive.
9337                         if (perm.modeFlags == 0) {
9338                             it.remove();
9339                         }
9340                     }
9341                 }
9342
9343                 if (perms.isEmpty()) {
9344                     mGrantedUriPermissions.remove(targetUid);
9345                     N--;
9346                     i--;
9347                 }
9348             }
9349         }
9350
9351         if (persistChanged) {
9352             schedulePersistUriGrants();
9353         }
9354     }
9355
9356     @Override
9357     public IBinder newUriPermissionOwner(String name) {
9358         enforceNotIsolatedCaller("newUriPermissionOwner");
9359         synchronized(this) {
9360             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9361             return owner.getExternalTokenLocked();
9362         }
9363     }
9364
9365     @Override
9366     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9367         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9368         synchronized(this) {
9369             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9370             if (r == null) {
9371                 throw new IllegalArgumentException("Activity does not exist; token="
9372                         + activityToken);
9373             }
9374             return r.getUriPermissionsLocked().getExternalTokenLocked();
9375         }
9376     }
9377     /**
9378      * @param uri This uri must NOT contain an embedded userId.
9379      * @param sourceUserId The userId in which the uri is to be resolved.
9380      * @param targetUserId The userId of the app that receives the grant.
9381      */
9382     @Override
9383     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9384             final int modeFlags, int sourceUserId, int targetUserId) {
9385         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9386                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9387                 "grantUriPermissionFromOwner", null);
9388         synchronized(this) {
9389             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9390             if (owner == null) {
9391                 throw new IllegalArgumentException("Unknown owner: " + token);
9392             }
9393             if (fromUid != Binder.getCallingUid()) {
9394                 if (Binder.getCallingUid() != myUid()) {
9395                     // Only system code can grant URI permissions on behalf
9396                     // of other users.
9397                     throw new SecurityException("nice try");
9398                 }
9399             }
9400             if (targetPkg == null) {
9401                 throw new IllegalArgumentException("null target");
9402             }
9403             if (uri == null) {
9404                 throw new IllegalArgumentException("null uri");
9405             }
9406
9407             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9408                     modeFlags, owner, targetUserId);
9409         }
9410     }
9411
9412     /**
9413      * @param uri This uri must NOT contain an embedded userId.
9414      * @param userId The userId in which the uri is to be resolved.
9415      */
9416     @Override
9417     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9418         synchronized(this) {
9419             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9420             if (owner == null) {
9421                 throw new IllegalArgumentException("Unknown owner: " + token);
9422             }
9423
9424             if (uri == null) {
9425                 owner.removeUriPermissionsLocked(mode);
9426             } else {
9427                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9428                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9429             }
9430         }
9431     }
9432
9433     private void schedulePersistUriGrants() {
9434         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9435             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9436                     10 * DateUtils.SECOND_IN_MILLIS);
9437         }
9438     }
9439
9440     private void writeGrantedUriPermissions() {
9441         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9442
9443         // Snapshot permissions so we can persist without lock
9444         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9445         synchronized (this) {
9446             final int size = mGrantedUriPermissions.size();
9447             for (int i = 0; i < size; i++) {
9448                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9449                 for (UriPermission perm : perms.values()) {
9450                     if (perm.persistedModeFlags != 0) {
9451                         persist.add(perm.snapshot());
9452                     }
9453                 }
9454             }
9455         }
9456
9457         FileOutputStream fos = null;
9458         try {
9459             fos = mGrantFile.startWrite();
9460
9461             XmlSerializer out = new FastXmlSerializer();
9462             out.setOutput(fos, StandardCharsets.UTF_8.name());
9463             out.startDocument(null, true);
9464             out.startTag(null, TAG_URI_GRANTS);
9465             for (UriPermission.Snapshot perm : persist) {
9466                 out.startTag(null, TAG_URI_GRANT);
9467                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9468                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9469                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9470                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9471                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9472                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9473                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9474                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9475                 out.endTag(null, TAG_URI_GRANT);
9476             }
9477             out.endTag(null, TAG_URI_GRANTS);
9478             out.endDocument();
9479
9480             mGrantFile.finishWrite(fos);
9481         } catch (IOException e) {
9482             if (fos != null) {
9483                 mGrantFile.failWrite(fos);
9484             }
9485         }
9486     }
9487
9488     private void readGrantedUriPermissionsLocked() {
9489         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9490
9491         final long now = System.currentTimeMillis();
9492
9493         FileInputStream fis = null;
9494         try {
9495             fis = mGrantFile.openRead();
9496             final XmlPullParser in = Xml.newPullParser();
9497             in.setInput(fis, StandardCharsets.UTF_8.name());
9498
9499             int type;
9500             while ((type = in.next()) != END_DOCUMENT) {
9501                 final String tag = in.getName();
9502                 if (type == START_TAG) {
9503                     if (TAG_URI_GRANT.equals(tag)) {
9504                         final int sourceUserId;
9505                         final int targetUserId;
9506                         final int userHandle = readIntAttribute(in,
9507                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9508                         if (userHandle != UserHandle.USER_NULL) {
9509                             // For backwards compatibility.
9510                             sourceUserId = userHandle;
9511                             targetUserId = userHandle;
9512                         } else {
9513                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9514                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9515                         }
9516                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9517                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9518                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9519                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9520                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9521                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9522
9523                         // Sanity check that provider still belongs to source package
9524                         // Both direct boot aware and unaware packages are fine as we
9525                         // will do filtering at query time to avoid multiple parsing.
9526                         final ProviderInfo pi = getProviderInfoLocked(
9527                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9528                                         | MATCH_DIRECT_BOOT_UNAWARE);
9529                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9530                             int targetUid = -1;
9531                             try {
9532                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9533                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9534                             } catch (RemoteException e) {
9535                             }
9536                             if (targetUid != -1) {
9537                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9538                                         sourcePkg, targetPkg, targetUid,
9539                                         new GrantUri(sourceUserId, uri, prefix));
9540                                 perm.initPersistedModes(modeFlags, createdTime);
9541                             }
9542                         } else {
9543                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9544                                     + " but instead found " + pi);
9545                         }
9546                     }
9547                 }
9548             }
9549         } catch (FileNotFoundException e) {
9550             // Missing grants is okay
9551         } catch (IOException e) {
9552             Slog.wtf(TAG, "Failed reading Uri grants", e);
9553         } catch (XmlPullParserException e) {
9554             Slog.wtf(TAG, "Failed reading Uri grants", e);
9555         } finally {
9556             IoUtils.closeQuietly(fis);
9557         }
9558     }
9559
9560     /**
9561      * @param uri This uri must NOT contain an embedded userId.
9562      * @param userId The userId in which the uri is to be resolved.
9563      */
9564     @Override
9565     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9566         enforceNotIsolatedCaller("takePersistableUriPermission");
9567
9568         Preconditions.checkFlagsArgument(modeFlags,
9569                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9570
9571         synchronized (this) {
9572             final int callingUid = Binder.getCallingUid();
9573             boolean persistChanged = false;
9574             GrantUri grantUri = new GrantUri(userId, uri, false);
9575
9576             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9577                     new GrantUri(userId, uri, false));
9578             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9579                     new GrantUri(userId, uri, true));
9580
9581             final boolean exactValid = (exactPerm != null)
9582                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9583             final boolean prefixValid = (prefixPerm != null)
9584                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9585
9586             if (!(exactValid || prefixValid)) {
9587                 throw new SecurityException("No persistable permission grants found for UID "
9588                         + callingUid + " and Uri " + grantUri.toSafeString());
9589             }
9590
9591             if (exactValid) {
9592                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9593             }
9594             if (prefixValid) {
9595                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9596             }
9597
9598             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9599
9600             if (persistChanged) {
9601                 schedulePersistUriGrants();
9602             }
9603         }
9604     }
9605
9606     /**
9607      * @param uri This uri must NOT contain an embedded userId.
9608      * @param userId The userId in which the uri is to be resolved.
9609      */
9610     @Override
9611     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9612         enforceNotIsolatedCaller("releasePersistableUriPermission");
9613
9614         Preconditions.checkFlagsArgument(modeFlags,
9615                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9616
9617         synchronized (this) {
9618             final int callingUid = Binder.getCallingUid();
9619             boolean persistChanged = false;
9620
9621             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9622                     new GrantUri(userId, uri, false));
9623             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9624                     new GrantUri(userId, uri, true));
9625             if (exactPerm == null && prefixPerm == null) {
9626                 throw new SecurityException("No permission grants found for UID " + callingUid
9627                         + " and Uri " + uri.toSafeString());
9628             }
9629
9630             if (exactPerm != null) {
9631                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9632                 removeUriPermissionIfNeededLocked(exactPerm);
9633             }
9634             if (prefixPerm != null) {
9635                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9636                 removeUriPermissionIfNeededLocked(prefixPerm);
9637             }
9638
9639             if (persistChanged) {
9640                 schedulePersistUriGrants();
9641             }
9642         }
9643     }
9644
9645     /**
9646      * Prune any older {@link UriPermission} for the given UID until outstanding
9647      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9648      *
9649      * @return if any mutations occured that require persisting.
9650      */
9651     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9652         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9653         if (perms == null) return false;
9654         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9655
9656         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9657         for (UriPermission perm : perms.values()) {
9658             if (perm.persistedModeFlags != 0) {
9659                 persisted.add(perm);
9660             }
9661         }
9662
9663         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9664         if (trimCount <= 0) return false;
9665
9666         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9667         for (int i = 0; i < trimCount; i++) {
9668             final UriPermission perm = persisted.get(i);
9669
9670             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9671                     "Trimming grant created at " + perm.persistedCreateTime);
9672
9673             perm.releasePersistableModes(~0);
9674             removeUriPermissionIfNeededLocked(perm);
9675         }
9676
9677         return true;
9678     }
9679
9680     @Override
9681     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9682             String packageName, boolean incoming) {
9683         enforceNotIsolatedCaller("getPersistedUriPermissions");
9684         Preconditions.checkNotNull(packageName, "packageName");
9685
9686         final int callingUid = Binder.getCallingUid();
9687         final int callingUserId = UserHandle.getUserId(callingUid);
9688         final IPackageManager pm = AppGlobals.getPackageManager();
9689         try {
9690             final int packageUid = pm.getPackageUid(packageName,
9691                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9692             if (packageUid != callingUid) {
9693                 throw new SecurityException(
9694                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9695             }
9696         } catch (RemoteException e) {
9697             throw new SecurityException("Failed to verify package name ownership");
9698         }
9699
9700         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9701         synchronized (this) {
9702             if (incoming) {
9703                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9704                         callingUid);
9705                 if (perms == null) {
9706                     Slog.w(TAG, "No permission grants found for " + packageName);
9707                 } else {
9708                     for (UriPermission perm : perms.values()) {
9709                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9710                             result.add(perm.buildPersistedPublicApiObject());
9711                         }
9712                     }
9713                 }
9714             } else {
9715                 final int size = mGrantedUriPermissions.size();
9716                 for (int i = 0; i < size; i++) {
9717                     final ArrayMap<GrantUri, UriPermission> perms =
9718                             mGrantedUriPermissions.valueAt(i);
9719                     for (UriPermission perm : perms.values()) {
9720                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9721                             result.add(perm.buildPersistedPublicApiObject());
9722                         }
9723                     }
9724                 }
9725             }
9726         }
9727         return new ParceledListSlice<android.content.UriPermission>(result);
9728     }
9729
9730     @Override
9731     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9732             String packageName, int userId) {
9733         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9734                 "getGrantedUriPermissions");
9735
9736         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9737         synchronized (this) {
9738             final int size = mGrantedUriPermissions.size();
9739             for (int i = 0; i < size; i++) {
9740                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9741                 for (UriPermission perm : perms.values()) {
9742                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9743                             && perm.persistedModeFlags != 0) {
9744                         result.add(perm.buildPersistedPublicApiObject());
9745                     }
9746                 }
9747             }
9748         }
9749         return new ParceledListSlice<android.content.UriPermission>(result);
9750     }
9751
9752     @Override
9753     public void clearGrantedUriPermissions(String packageName, int userId) {
9754         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9755                 "clearGrantedUriPermissions");
9756         removeUriPermissionsForPackageLocked(packageName, userId, true);
9757     }
9758
9759     @Override
9760     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9761         synchronized (this) {
9762             ProcessRecord app =
9763                 who != null ? getRecordForAppLocked(who) : null;
9764             if (app == null) return;
9765
9766             Message msg = Message.obtain();
9767             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9768             msg.obj = app;
9769             msg.arg1 = waiting ? 1 : 0;
9770             mUiHandler.sendMessage(msg);
9771         }
9772     }
9773
9774     @Override
9775     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9776         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9777         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9778         outInfo.availMem = getFreeMemory();
9779         outInfo.totalMem = getTotalMemory();
9780         outInfo.threshold = homeAppMem;
9781         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9782         outInfo.hiddenAppThreshold = cachedAppMem;
9783         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9784                 ProcessList.SERVICE_ADJ);
9785         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9786                 ProcessList.VISIBLE_APP_ADJ);
9787         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9788                 ProcessList.FOREGROUND_APP_ADJ);
9789     }
9790
9791     // =========================================================
9792     // TASK MANAGEMENT
9793     // =========================================================
9794
9795     @Override
9796     public List<IBinder> getAppTasks(String callingPackage) {
9797         int callingUid = Binder.getCallingUid();
9798         long ident = Binder.clearCallingIdentity();
9799
9800         synchronized(this) {
9801             ArrayList<IBinder> list = new ArrayList<IBinder>();
9802             try {
9803                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9804
9805                 final int N = mRecentTasks.size();
9806                 for (int i = 0; i < N; i++) {
9807                     TaskRecord tr = mRecentTasks.get(i);
9808                     // Skip tasks that do not match the caller.  We don't need to verify
9809                     // callingPackage, because we are also limiting to callingUid and know
9810                     // that will limit to the correct security sandbox.
9811                     if (tr.effectiveUid != callingUid) {
9812                         continue;
9813                     }
9814                     Intent intent = tr.getBaseIntent();
9815                     if (intent == null ||
9816                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9817                         continue;
9818                     }
9819                     ActivityManager.RecentTaskInfo taskInfo =
9820                             createRecentTaskInfoFromTaskRecord(tr);
9821                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9822                     list.add(taskImpl.asBinder());
9823                 }
9824             } finally {
9825                 Binder.restoreCallingIdentity(ident);
9826             }
9827             return list;
9828         }
9829     }
9830
9831     @Override
9832     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9833         final int callingUid = Binder.getCallingUid();
9834         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9835
9836         synchronized(this) {
9837             if (DEBUG_ALL) Slog.v(
9838                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9839
9840             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9841                     callingUid);
9842
9843             // TODO: Improve with MRU list from all ActivityStacks.
9844             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9845         }
9846
9847         return list;
9848     }
9849
9850     /**
9851      * Creates a new RecentTaskInfo from a TaskRecord.
9852      */
9853     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9854         // Update the task description to reflect any changes in the task stack
9855         tr.updateTaskDescription();
9856
9857         // Compose the recent task info
9858         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9859         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9860         rti.persistentId = tr.taskId;
9861         rti.baseIntent = new Intent(tr.getBaseIntent());
9862         rti.origActivity = tr.origActivity;
9863         rti.realActivity = tr.realActivity;
9864         rti.description = tr.lastDescription;
9865         rti.stackId = tr.getStackId();
9866         rti.userId = tr.userId;
9867         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9868         rti.firstActiveTime = tr.firstActiveTime;
9869         rti.lastActiveTime = tr.lastActiveTime;
9870         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9871         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9872         rti.numActivities = 0;
9873         if (tr.mBounds != null) {
9874             rti.bounds = new Rect(tr.mBounds);
9875         }
9876         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9877         rti.resizeMode = tr.mResizeMode;
9878
9879         ActivityRecord base = null;
9880         ActivityRecord top = null;
9881         ActivityRecord tmp;
9882
9883         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9884             tmp = tr.mActivities.get(i);
9885             if (tmp.finishing) {
9886                 continue;
9887             }
9888             base = tmp;
9889             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9890                 top = base;
9891             }
9892             rti.numActivities++;
9893         }
9894
9895         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9896         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9897
9898         return rti;
9899     }
9900
9901     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9902         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9903                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9904         if (!allowed) {
9905             if (checkPermission(android.Manifest.permission.GET_TASKS,
9906                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9907                 // Temporary compatibility: some existing apps on the system image may
9908                 // still be requesting the old permission and not switched to the new
9909                 // one; if so, we'll still allow them full access.  This means we need
9910                 // to see if they are holding the old permission and are a system app.
9911                 try {
9912                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9913                         allowed = true;
9914                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9915                                 + " is using old GET_TASKS but privileged; allowing");
9916                     }
9917                 } catch (RemoteException e) {
9918                 }
9919             }
9920         }
9921         if (!allowed) {
9922             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9923                     + " does not hold REAL_GET_TASKS; limiting output");
9924         }
9925         return allowed;
9926     }
9927
9928     @Override
9929     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9930             int userId) {
9931         final int callingUid = Binder.getCallingUid();
9932         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9933                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9934
9935         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9936         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9937         synchronized (this) {
9938             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9939                     callingUid);
9940             final boolean detailed = checkCallingPermission(
9941                     android.Manifest.permission.GET_DETAILED_TASKS)
9942                     == PackageManager.PERMISSION_GRANTED;
9943
9944             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9945                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9946                 return ParceledListSlice.emptyList();
9947             }
9948             mRecentTasks.loadUserRecentsLocked(userId);
9949
9950             final int recentsCount = mRecentTasks.size();
9951             ArrayList<ActivityManager.RecentTaskInfo> res =
9952                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9953
9954             final Set<Integer> includedUsers;
9955             if (includeProfiles) {
9956                 includedUsers = mUserController.getProfileIds(userId);
9957             } else {
9958                 includedUsers = new HashSet<>();
9959             }
9960             includedUsers.add(Integer.valueOf(userId));
9961
9962             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9963                 TaskRecord tr = mRecentTasks.get(i);
9964                 // Only add calling user or related users recent tasks
9965                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9966                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9967                     continue;
9968                 }
9969
9970                 if (tr.realActivitySuspended) {
9971                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9972                     continue;
9973                 }
9974
9975                 // Return the entry if desired by the caller.  We always return
9976                 // the first entry, because callers always expect this to be the
9977                 // foreground app.  We may filter others if the caller has
9978                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9979                 // we should exclude the entry.
9980
9981                 if (i == 0
9982                         || withExcluded
9983                         || (tr.intent == null)
9984                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9985                                 == 0)) {
9986                     if (!allowed) {
9987                         // If the caller doesn't have the GET_TASKS permission, then only
9988                         // allow them to see a small subset of tasks -- their own and home.
9989                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9990                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9991                             continue;
9992                         }
9993                     }
9994                     final ActivityStack stack = tr.getStack();
9995                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
9996                         if (stack != null && stack.isHomeOrRecentsStack()) {
9997                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9998                                     "Skipping, home or recents stack task: " + tr);
9999                             continue;
10000                         }
10001                     }
10002                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10003                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10004                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10005                                     "Skipping, top task in docked stack: " + tr);
10006                             continue;
10007                         }
10008                     }
10009                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10010                         if (stack != null && stack.isPinnedStack()) {
10011                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10012                                     "Skipping, pinned stack task: " + tr);
10013                             continue;
10014                         }
10015                     }
10016                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10017                         // Don't include auto remove tasks that are finished or finishing.
10018                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10019                                 "Skipping, auto-remove without activity: " + tr);
10020                         continue;
10021                     }
10022                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10023                             && !tr.isAvailable) {
10024                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025                                 "Skipping, unavail real act: " + tr);
10026                         continue;
10027                     }
10028
10029                     if (!tr.mUserSetupComplete) {
10030                         // Don't include task launched while user is not done setting-up.
10031                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10032                                 "Skipping, user setup not complete: " + tr);
10033                         continue;
10034                     }
10035
10036                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10037                     if (!detailed) {
10038                         rti.baseIntent.replaceExtras((Bundle)null);
10039                     }
10040
10041                     res.add(rti);
10042                     maxNum--;
10043                 }
10044             }
10045             return new ParceledListSlice<>(res);
10046         }
10047     }
10048
10049     @Override
10050     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10051         synchronized (this) {
10052             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10053                     "getTaskThumbnail()");
10054             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10055                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10056             if (tr != null) {
10057                 return tr.getTaskThumbnailLocked();
10058             }
10059         }
10060         return null;
10061     }
10062
10063     @Override
10064     public ActivityManager.TaskDescription getTaskDescription(int id) {
10065         synchronized (this) {
10066             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10067                     "getTaskDescription()");
10068             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10069                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10070             if (tr != null) {
10071                 return tr.lastTaskDescription;
10072             }
10073         }
10074         return null;
10075     }
10076
10077     @Override
10078     public int addAppTask(IBinder activityToken, Intent intent,
10079             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10080         final int callingUid = Binder.getCallingUid();
10081         final long callingIdent = Binder.clearCallingIdentity();
10082
10083         try {
10084             synchronized (this) {
10085                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10086                 if (r == null) {
10087                     throw new IllegalArgumentException("Activity does not exist; token="
10088                             + activityToken);
10089                 }
10090                 ComponentName comp = intent.getComponent();
10091                 if (comp == null) {
10092                     throw new IllegalArgumentException("Intent " + intent
10093                             + " must specify explicit component");
10094                 }
10095                 if (thumbnail.getWidth() != mThumbnailWidth
10096                         || thumbnail.getHeight() != mThumbnailHeight) {
10097                     throw new IllegalArgumentException("Bad thumbnail size: got "
10098                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10099                             + mThumbnailWidth + "x" + mThumbnailHeight);
10100                 }
10101                 if (intent.getSelector() != null) {
10102                     intent.setSelector(null);
10103                 }
10104                 if (intent.getSourceBounds() != null) {
10105                     intent.setSourceBounds(null);
10106                 }
10107                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10108                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10109                         // The caller has added this as an auto-remove task...  that makes no
10110                         // sense, so turn off auto-remove.
10111                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10112                     }
10113                 }
10114                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10115                     mLastAddedTaskActivity = null;
10116                 }
10117                 ActivityInfo ainfo = mLastAddedTaskActivity;
10118                 if (ainfo == null) {
10119                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10120                             comp, 0, UserHandle.getUserId(callingUid));
10121                     if (ainfo.applicationInfo.uid != callingUid) {
10122                         throw new SecurityException(
10123                                 "Can't add task for another application: target uid="
10124                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10125                     }
10126                 }
10127
10128                 TaskRecord task = new TaskRecord(this,
10129                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10130                         ainfo, intent, description, new TaskThumbnailInfo());
10131
10132                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10133                 if (trimIdx >= 0) {
10134                     // If this would have caused a trim, then we'll abort because that
10135                     // means it would be added at the end of the list but then just removed.
10136                     return INVALID_TASK_ID;
10137                 }
10138
10139                 final int N = mRecentTasks.size();
10140                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10141                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10142                     tr.removedFromRecents();
10143                 }
10144
10145                 task.inRecents = true;
10146                 mRecentTasks.add(task);
10147                 r.getStack().addTask(task, false, "addAppTask");
10148
10149                 task.setLastThumbnailLocked(thumbnail);
10150                 task.freeLastThumbnail();
10151                 return task.taskId;
10152             }
10153         } finally {
10154             Binder.restoreCallingIdentity(callingIdent);
10155         }
10156     }
10157
10158     @Override
10159     public Point getAppTaskThumbnailSize() {
10160         synchronized (this) {
10161             return new Point(mThumbnailWidth,  mThumbnailHeight);
10162         }
10163     }
10164
10165     @Override
10166     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10167         synchronized (this) {
10168             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10169             if (r != null) {
10170                 r.setTaskDescription(td);
10171                 final TaskRecord task = r.getTask();
10172                 task.updateTaskDescription();
10173                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10174             }
10175         }
10176     }
10177
10178     @Override
10179     public void setTaskResizeable(int taskId, int resizeableMode) {
10180         synchronized (this) {
10181             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10182                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10183             if (task == null) {
10184                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10185                 return;
10186             }
10187             task.setResizeMode(resizeableMode);
10188         }
10189     }
10190
10191     @Override
10192     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10193         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10194         long ident = Binder.clearCallingIdentity();
10195         try {
10196             synchronized (this) {
10197                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10198                 if (task == null) {
10199                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10200                     return;
10201                 }
10202                 // Place the task in the right stack if it isn't there already based on
10203                 // the requested bounds.
10204                 // The stack transition logic is:
10205                 // - a null bounds on a freeform task moves that task to fullscreen
10206                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10207                 //   that task to freeform
10208                 // - otherwise the task is not moved
10209                 int stackId = task.getStackId();
10210                 if (!StackId.isTaskResizeAllowed(stackId)) {
10211                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10212                 }
10213                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10214                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10215                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10216                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10217                 }
10218
10219                 // Reparent the task to the right stack if necessary
10220                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10221                 if (stackId != task.getStackId()) {
10222                     // Defer resume until the task is resized below
10223                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10224                             DEFER_RESUME, "resizeTask");
10225                     preserveWindow = false;
10226                 }
10227
10228                 // After reparenting (which only resizes the task to the stack bounds), resize the
10229                 // task to the actual bounds provided
10230                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10231             }
10232         } finally {
10233             Binder.restoreCallingIdentity(ident);
10234         }
10235     }
10236
10237     @Override
10238     public Rect getTaskBounds(int taskId) {
10239         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10240         long ident = Binder.clearCallingIdentity();
10241         Rect rect = new Rect();
10242         try {
10243             synchronized (this) {
10244                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10245                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10246                 if (task == null) {
10247                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10248                     return rect;
10249                 }
10250                 if (task.getStack() != null) {
10251                     // Return the bounds from window manager since it will be adjusted for various
10252                     // things like the presense of a docked stack for tasks that aren't resizeable.
10253                     task.getWindowContainerBounds(rect);
10254                 } else {
10255                     // Task isn't in window manager yet since it isn't associated with a stack.
10256                     // Return the persist value from activity manager
10257                     if (task.mBounds != null) {
10258                         rect.set(task.mBounds);
10259                     } else if (task.mLastNonFullscreenBounds != null) {
10260                         rect.set(task.mLastNonFullscreenBounds);
10261                     }
10262                 }
10263             }
10264         } finally {
10265             Binder.restoreCallingIdentity(ident);
10266         }
10267         return rect;
10268     }
10269
10270     @Override
10271     public void cancelTaskWindowTransition(int taskId) {
10272         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10273         final long ident = Binder.clearCallingIdentity();
10274         try {
10275             synchronized (this) {
10276                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10277                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10278                 if (task == null) {
10279                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10280                     return;
10281                 }
10282                 task.cancelWindowTransition();
10283             }
10284         } finally {
10285             Binder.restoreCallingIdentity(ident);
10286         }
10287     }
10288
10289     @Override
10290     public void cancelTaskThumbnailTransition(int taskId) {
10291         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10292         final long ident = Binder.clearCallingIdentity();
10293         try {
10294             synchronized (this) {
10295                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10296                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10297                 if (task == null) {
10298                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10299                     return;
10300                 }
10301                 task.cancelThumbnailTransition();
10302             }
10303         } finally {
10304             Binder.restoreCallingIdentity(ident);
10305         }
10306     }
10307
10308     @Override
10309     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10310         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10311         final long ident = Binder.clearCallingIdentity();
10312         try {
10313             final TaskRecord task;
10314             synchronized (this) {
10315                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10316                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10317                 if (task == null) {
10318                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10319                     return null;
10320                 }
10321             }
10322             // Don't call this while holding the lock as this operation might hit the disk.
10323             return task.getSnapshot(reducedResolution);
10324         } finally {
10325             Binder.restoreCallingIdentity(ident);
10326         }
10327     }
10328
10329     @Override
10330     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10331         if (userId != UserHandle.getCallingUserId()) {
10332             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10333                     "getTaskDescriptionIcon");
10334         }
10335         final File passedIconFile = new File(filePath);
10336         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10337                 passedIconFile.getName());
10338         if (!legitIconFile.getPath().equals(filePath)
10339                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10340             throw new IllegalArgumentException("Bad file path: " + filePath
10341                     + " passed for userId " + userId);
10342         }
10343         return mRecentTasks.getTaskDescriptionIcon(filePath);
10344     }
10345
10346     @Override
10347     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10348             throws RemoteException {
10349         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10350         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10351                 activityOptions.getCustomInPlaceResId() == 0) {
10352             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10353                     "with valid animation");
10354         }
10355         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10356         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10357                 activityOptions.getCustomInPlaceResId());
10358         mWindowManager.executeAppTransition();
10359     }
10360
10361     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10362         // Remove all tasks with activities in the specified package from the list of recent tasks
10363         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10364             TaskRecord tr = mRecentTasks.get(i);
10365             if (tr.userId != userId) continue;
10366
10367             ComponentName cn = tr.intent.getComponent();
10368             if (cn != null && cn.getPackageName().equals(packageName)) {
10369                 // If the package name matches, remove the task.
10370                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10371             }
10372         }
10373     }
10374
10375     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10376             int userId) {
10377
10378         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10379             TaskRecord tr = mRecentTasks.get(i);
10380             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10381                 continue;
10382             }
10383
10384             ComponentName cn = tr.intent.getComponent();
10385             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10386                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10387             if (sameComponent) {
10388                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10389             }
10390         }
10391     }
10392
10393     @Override
10394     public void removeStack(int stackId) {
10395         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10396         if (StackId.isHomeOrRecentsStack(stackId)) {
10397             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10398         }
10399
10400         synchronized (this) {
10401             final long ident = Binder.clearCallingIdentity();
10402             try {
10403                 mStackSupervisor.removeStackLocked(stackId);
10404             } finally {
10405                 Binder.restoreCallingIdentity(ident);
10406             }
10407         }
10408     }
10409
10410     @Override
10411     public void moveStackToDisplay(int stackId, int displayId) {
10412         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10413
10414         synchronized (this) {
10415             final long ident = Binder.clearCallingIdentity();
10416             try {
10417                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10418                         + " to displayId=" + displayId);
10419                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10420             } finally {
10421                 Binder.restoreCallingIdentity(ident);
10422             }
10423         }
10424     }
10425
10426     @Override
10427     public boolean removeTask(int taskId) {
10428         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10429         synchronized (this) {
10430             final long ident = Binder.clearCallingIdentity();
10431             try {
10432                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10433             } finally {
10434                 Binder.restoreCallingIdentity(ident);
10435             }
10436         }
10437     }
10438
10439     /**
10440      * TODO: Add mController hook
10441      */
10442     @Override
10443     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10444         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10445
10446         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10447         synchronized(this) {
10448             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10449         }
10450     }
10451
10452     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10453         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10454
10455         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10456                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10457             ActivityOptions.abort(options);
10458             return;
10459         }
10460         final long origId = Binder.clearCallingIdentity();
10461         try {
10462             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10463             if (task == null) {
10464                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10465                 return;
10466             }
10467             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10468                 mStackSupervisor.showLockTaskToast();
10469                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10470                 return;
10471             }
10472             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10473             if (prev != null) {
10474                 task.setTaskToReturnTo(prev);
10475             }
10476             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10477                     false /* forceNonResizable */);
10478
10479             final ActivityRecord topActivity = task.getTopActivity();
10480             if (topActivity != null) {
10481
10482                 // We are reshowing a task, use a starting window to hide the initial draw delay
10483                 // so the transition can start earlier.
10484                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10485                         true /* taskSwitch */, fromRecents);
10486             }
10487         } finally {
10488             Binder.restoreCallingIdentity(origId);
10489         }
10490         ActivityOptions.abort(options);
10491     }
10492
10493     /**
10494      * Attempts to move a task backwards in z-order (the order of activities within the task is
10495      * unchanged).
10496      *
10497      * There are several possible results of this call:
10498      * - if the task is locked, then we will show the lock toast
10499      * - if there is a task behind the provided task, then that task is made visible and resumed as
10500      *   this task is moved to the back
10501      * - otherwise, if there are no other tasks in the stack:
10502      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10503      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10504      *       (depending on whether it is visible)
10505      *     - otherwise, we simply return home and hide this task
10506      *
10507      * @param token A reference to the activity we wish to move
10508      * @param nonRoot If false then this only works if the activity is the root
10509      *                of a task; if true it will work for any activity in a task.
10510      * @return Returns true if the move completed, false if not.
10511      */
10512     @Override
10513     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10514         enforceNotIsolatedCaller("moveActivityTaskToBack");
10515         synchronized(this) {
10516             final long origId = Binder.clearCallingIdentity();
10517             try {
10518                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10519                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10520                 if (task != null) {
10521                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10522                 }
10523             } finally {
10524                 Binder.restoreCallingIdentity(origId);
10525             }
10526         }
10527         return false;
10528     }
10529
10530     @Override
10531     public void moveTaskBackwards(int task) {
10532         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10533                 "moveTaskBackwards()");
10534
10535         synchronized(this) {
10536             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10537                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10538                 return;
10539             }
10540             final long origId = Binder.clearCallingIdentity();
10541             moveTaskBackwardsLocked(task);
10542             Binder.restoreCallingIdentity(origId);
10543         }
10544     }
10545
10546     private final void moveTaskBackwardsLocked(int task) {
10547         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10548     }
10549
10550     @Override
10551     public int createStackOnDisplay(int displayId) throws RemoteException {
10552         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10553         synchronized (this) {
10554             final int stackId = mStackSupervisor.getNextStackId();
10555             final ActivityStack stack =
10556                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10557             if (stack == null) {
10558                 return INVALID_STACK_ID;
10559             }
10560             return stack.mStackId;
10561         }
10562     }
10563
10564     @Override
10565     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10566         synchronized (this) {
10567             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10568             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10569                 return stack.mDisplayId;
10570             }
10571             return DEFAULT_DISPLAY;
10572         }
10573     }
10574
10575     @Override
10576     public int getActivityStackId(IBinder token) throws RemoteException {
10577         synchronized (this) {
10578             ActivityStack stack = ActivityRecord.getStackLocked(token);
10579             if (stack == null) {
10580                 return INVALID_STACK_ID;
10581             }
10582             return stack.mStackId;
10583         }
10584     }
10585
10586     @Override
10587     public void exitFreeformMode(IBinder token) throws RemoteException {
10588         synchronized (this) {
10589             long ident = Binder.clearCallingIdentity();
10590             try {
10591                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10592                 if (r == null) {
10593                     throw new IllegalArgumentException(
10594                             "exitFreeformMode: No activity record matching token=" + token);
10595                 }
10596
10597                 final ActivityStack stack = r.getStack();
10598                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10599                     throw new IllegalStateException(
10600                             "exitFreeformMode: You can only go fullscreen from freeform.");
10601                 }
10602
10603                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10604                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10605                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10606             } finally {
10607                 Binder.restoreCallingIdentity(ident);
10608             }
10609         }
10610     }
10611
10612     @Override
10613     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10614         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10615         if (StackId.isHomeOrRecentsStack(stackId)) {
10616             throw new IllegalArgumentException(
10617                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10618         }
10619         synchronized (this) {
10620             long ident = Binder.clearCallingIdentity();
10621             try {
10622                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10623                 if (task == null) {
10624                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10625                     return;
10626                 }
10627
10628                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10629                         + " to stackId=" + stackId + " toTop=" + toTop);
10630                 if (stackId == DOCKED_STACK_ID) {
10631                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10632                             null /* initialBounds */);
10633                 }
10634                 task.reparent(stackId, toTop,
10635                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10636             } finally {
10637                 Binder.restoreCallingIdentity(ident);
10638             }
10639         }
10640     }
10641
10642     @Override
10643     public void swapDockedAndFullscreenStack() throws RemoteException {
10644         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10645         synchronized (this) {
10646             long ident = Binder.clearCallingIdentity();
10647             try {
10648                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10649                         FULLSCREEN_WORKSPACE_STACK_ID);
10650                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10651                         : null;
10652                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10653                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10654                         : null;
10655                 if (topTask == null || tasks == null || tasks.size() == 0) {
10656                     Slog.w(TAG,
10657                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10658                     return;
10659                 }
10660
10661                 // TODO: App transition
10662                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10663
10664                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10665                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10666                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10667                 final int size = tasks.size();
10668                 for (int i = 0; i < size; i++) {
10669                     final int id = tasks.get(i).taskId;
10670                     if (id == topTask.taskId) {
10671                         continue;
10672                     }
10673
10674                     // Defer the resume until after all the tasks have been moved
10675                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10676                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10677                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10678                 }
10679
10680                 // Because we deferred the resume to avoid conflicts with stack switches while
10681                 // resuming, we need to do it after all the tasks are moved.
10682                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10683                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10684
10685                 mWindowManager.executeAppTransition();
10686             } finally {
10687                 Binder.restoreCallingIdentity(ident);
10688             }
10689         }
10690     }
10691
10692     /**
10693      * Moves the input task to the docked stack.
10694      *
10695      * @param taskId Id of task to move.
10696      * @param createMode The mode the docked stack should be created in if it doesn't exist
10697      *                   already. See
10698      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10699      *                   and
10700      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10701      * @param toTop If the task and stack should be moved to the top.
10702      * @param animate Whether we should play an animation for the moving the task
10703      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10704      *                      docked stack. Pass {@code null} to use default bounds.
10705      */
10706     @Override
10707     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10708             Rect initialBounds) {
10709         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10710         synchronized (this) {
10711             long ident = Binder.clearCallingIdentity();
10712             try {
10713                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10714                 if (task == null) {
10715                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10716                     return false;
10717                 }
10718
10719                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10720                         + " to createMode=" + createMode + " toTop=" + toTop);
10721                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10722
10723                 // Defer resuming until we move the home stack to the front below
10724                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10725                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10726                         "moveTaskToDockedStack");
10727                 if (moved) {
10728                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10729                 }
10730                 return moved;
10731             } finally {
10732                 Binder.restoreCallingIdentity(ident);
10733             }
10734         }
10735     }
10736
10737     /**
10738      * Moves the top activity in the input stackId to the pinned stack.
10739      *
10740      * @param stackId Id of stack to move the top activity to pinned stack.
10741      * @param bounds Bounds to use for pinned stack.
10742      *
10743      * @return True if the top activity of the input stack was successfully moved to the pinned
10744      *          stack.
10745      */
10746     @Override
10747     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10748         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10749         synchronized (this) {
10750             if (!mSupportsPictureInPicture) {
10751                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10752                         + "Device doesn't support picture-in-picture mode");
10753             }
10754
10755             long ident = Binder.clearCallingIdentity();
10756             try {
10757                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10758             } finally {
10759                 Binder.restoreCallingIdentity(ident);
10760             }
10761         }
10762     }
10763
10764     @Override
10765     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10766             boolean preserveWindows, boolean animate, int animationDuration) {
10767         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10768         long ident = Binder.clearCallingIdentity();
10769         try {
10770             synchronized (this) {
10771                 if (animate) {
10772                     if (stackId == PINNED_STACK_ID) {
10773                         final PinnedActivityStack pinnedStack =
10774                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10775                         if (pinnedStack != null) {
10776                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10777                                     destBounds, animationDuration, false /* fromFullscreen */);
10778                         }
10779                     } else {
10780                         throw new IllegalArgumentException("Stack: " + stackId
10781                                 + " doesn't support animated resize.");
10782                     }
10783                 } else {
10784                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10785                             null /* tempTaskInsetBounds */, preserveWindows,
10786                             allowResizeInDockedMode, !DEFER_RESUME);
10787                 }
10788             }
10789         } finally {
10790             Binder.restoreCallingIdentity(ident);
10791         }
10792     }
10793
10794     @Override
10795     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10796             Rect tempDockedTaskInsetBounds,
10797             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10798         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10799                 "resizeDockedStack()");
10800         long ident = Binder.clearCallingIdentity();
10801         try {
10802             synchronized (this) {
10803                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10804                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10805                         PRESERVE_WINDOWS);
10806             }
10807         } finally {
10808             Binder.restoreCallingIdentity(ident);
10809         }
10810     }
10811
10812     @Override
10813     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10814         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10815                 "resizePinnedStack()");
10816         final long ident = Binder.clearCallingIdentity();
10817         try {
10818             synchronized (this) {
10819                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10820             }
10821         } finally {
10822             Binder.restoreCallingIdentity(ident);
10823         }
10824     }
10825
10826     /**
10827      * Try to place task to provided position. The final position might be different depending on
10828      * current user and stacks state. The task will be moved to target stack if it's currently in
10829      * different stack.
10830      */
10831     @Override
10832     public void positionTaskInStack(int taskId, int stackId, int position) {
10833         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10834         if (StackId.isHomeOrRecentsStack(stackId)) {
10835             throw new IllegalArgumentException(
10836                     "positionTaskInStack: Attempt to change the position of task "
10837                     + taskId + " in/to home/recents stack");
10838         }
10839         synchronized (this) {
10840             long ident = Binder.clearCallingIdentity();
10841             try {
10842                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10843                         + taskId + " in stackId=" + stackId + " at position=" + position);
10844                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10845                 if (task == null) {
10846                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10847                             + taskId);
10848                 }
10849
10850                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10851                         !ON_TOP);
10852
10853                 // TODO: Have the callers of this API call a separate reparent method if that is
10854                 // what they intended to do vs. having this method also do reparenting.
10855                 if (task.getStack() == stack) {
10856                     // Change position in current stack.
10857                     stack.positionChildAt(task, position);
10858                 } else {
10859                     // Reparent to new stack.
10860                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10861                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10862                 }
10863             } finally {
10864                 Binder.restoreCallingIdentity(ident);
10865             }
10866         }
10867     }
10868
10869     @Override
10870     public List<StackInfo> getAllStackInfos() {
10871         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10872         long ident = Binder.clearCallingIdentity();
10873         try {
10874             synchronized (this) {
10875                 return mStackSupervisor.getAllStackInfosLocked();
10876             }
10877         } finally {
10878             Binder.restoreCallingIdentity(ident);
10879         }
10880     }
10881
10882     @Override
10883     public StackInfo getStackInfo(int stackId) {
10884         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10885         long ident = Binder.clearCallingIdentity();
10886         try {
10887             synchronized (this) {
10888                 return mStackSupervisor.getStackInfoLocked(stackId);
10889             }
10890         } finally {
10891             Binder.restoreCallingIdentity(ident);
10892         }
10893     }
10894
10895     @Override
10896     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10897         synchronized(this) {
10898             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10899         }
10900     }
10901
10902     @Override
10903     public void updateDeviceOwner(String packageName) {
10904         final int callingUid = Binder.getCallingUid();
10905         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10906             throw new SecurityException("updateDeviceOwner called from non-system process");
10907         }
10908         synchronized (this) {
10909             mDeviceOwnerName = packageName;
10910         }
10911     }
10912
10913     @Override
10914     public void updateLockTaskPackages(int userId, String[] packages) {
10915         final int callingUid = Binder.getCallingUid();
10916         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10917             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10918                     "updateLockTaskPackages()");
10919         }
10920         synchronized (this) {
10921             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10922                     Arrays.toString(packages));
10923             mLockTaskPackages.put(userId, packages);
10924             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10925         }
10926     }
10927
10928
10929     void startLockTaskModeLocked(TaskRecord task) {
10930         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10931         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10932             return;
10933         }
10934
10935         // When a task is locked, dismiss the pinned stack if it exists
10936         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10937                 PINNED_STACK_ID);
10938         if (pinnedStack != null) {
10939             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10940         }
10941
10942         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10943         // is initiated by system after the pinning request was shown and locked mode is initiated
10944         // by an authorized app directly
10945         final int callingUid = Binder.getCallingUid();
10946         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10947         long ident = Binder.clearCallingIdentity();
10948         try {
10949             if (!isSystemInitiated) {
10950                 task.mLockTaskUid = callingUid;
10951                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10952                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10953                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10954                     StatusBarManagerInternal statusBarManager =
10955                             LocalServices.getService(StatusBarManagerInternal.class);
10956                     if (statusBarManager != null) {
10957                         statusBarManager.showScreenPinningRequest(task.taskId);
10958                     }
10959                     return;
10960                 }
10961
10962                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10963                 if (stack == null || task != stack.topTask()) {
10964                     throw new IllegalArgumentException("Invalid task, not in foreground");
10965                 }
10966             }
10967             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10968                     "Locking fully");
10969             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10970                     ActivityManager.LOCK_TASK_MODE_PINNED :
10971                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10972                     "startLockTask", true);
10973         } finally {
10974             Binder.restoreCallingIdentity(ident);
10975         }
10976     }
10977
10978     @Override
10979     public void startLockTaskModeById(int taskId) {
10980         synchronized (this) {
10981             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10982             if (task != null) {
10983                 startLockTaskModeLocked(task);
10984             }
10985         }
10986     }
10987
10988     @Override
10989     public void startLockTaskModeByToken(IBinder token) {
10990         synchronized (this) {
10991             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10992             if (r == null) {
10993                 return;
10994             }
10995             final TaskRecord task = r.getTask();
10996             if (task != null) {
10997                 startLockTaskModeLocked(task);
10998             }
10999         }
11000     }
11001
11002     @Override
11003     public void startSystemLockTaskMode(int taskId) throws RemoteException {
11004         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11005         // This makes inner call to look as if it was initiated by system.
11006         long ident = Binder.clearCallingIdentity();
11007         try {
11008             synchronized (this) {
11009                 startLockTaskModeById(taskId);
11010             }
11011         } finally {
11012             Binder.restoreCallingIdentity(ident);
11013         }
11014     }
11015
11016     @Override
11017     public void stopLockTaskMode() {
11018         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11019         if (lockTask == null) {
11020             // Our work here is done.
11021             return;
11022         }
11023
11024         final int callingUid = Binder.getCallingUid();
11025         final int lockTaskUid = lockTask.mLockTaskUid;
11026         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11027         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11028             // Done.
11029             return;
11030         } else {
11031             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11032             // It is possible lockTaskMode was started by the system process because
11033             // android:lockTaskMode is set to a locking value in the application manifest
11034             // instead of the app calling startLockTaskMode. In this case
11035             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11036             // {@link TaskRecord.effectiveUid} instead. Also caller with
11037             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11038             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11039                     && callingUid != lockTaskUid
11040                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11041                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11042                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11043             }
11044         }
11045         long ident = Binder.clearCallingIdentity();
11046         try {
11047             Log.d(TAG, "stopLockTaskMode");
11048             // Stop lock task
11049             synchronized (this) {
11050                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11051                         "stopLockTask", true);
11052             }
11053             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11054             if (tm != null) {
11055                 tm.showInCallScreen(false);
11056             }
11057         } finally {
11058             Binder.restoreCallingIdentity(ident);
11059         }
11060     }
11061
11062     /**
11063      * This API should be called by SystemUI only when user perform certain action to dismiss
11064      * lock task mode. We should only dismiss pinned lock task mode in this case.
11065      */
11066     @Override
11067     public void stopSystemLockTaskMode() throws RemoteException {
11068         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11069             stopLockTaskMode();
11070         } else {
11071             mStackSupervisor.showLockTaskToast();
11072         }
11073     }
11074
11075     @Override
11076     public boolean isInLockTaskMode() {
11077         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11078     }
11079
11080     @Override
11081     public int getLockTaskModeState() {
11082         synchronized (this) {
11083             return mStackSupervisor.getLockTaskModeState();
11084         }
11085     }
11086
11087     @Override
11088     public void showLockTaskEscapeMessage(IBinder token) {
11089         synchronized (this) {
11090             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11091             if (r == null) {
11092                 return;
11093             }
11094             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11095         }
11096     }
11097
11098     @Override
11099     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11100             throws RemoteException {
11101         synchronized (this) {
11102             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11103             if (r == null) {
11104                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11105                         + token);
11106                 return;
11107             }
11108             final long origId = Binder.clearCallingIdentity();
11109             try {
11110                 r.setDisablePreviewScreenshots(disable);
11111             } finally {
11112                 Binder.restoreCallingIdentity(origId);
11113             }
11114         }
11115     }
11116
11117     // =========================================================
11118     // CONTENT PROVIDERS
11119     // =========================================================
11120
11121     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11122         List<ProviderInfo> providers = null;
11123         try {
11124             providers = AppGlobals.getPackageManager()
11125                     .queryContentProviders(app.processName, app.uid,
11126                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11127                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11128                     .getList();
11129         } catch (RemoteException ex) {
11130         }
11131         if (DEBUG_MU) Slog.v(TAG_MU,
11132                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11133         int userId = app.userId;
11134         if (providers != null) {
11135             int N = providers.size();
11136             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11137             for (int i=0; i<N; i++) {
11138                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11139                 ProviderInfo cpi =
11140                     (ProviderInfo)providers.get(i);
11141                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11142                         cpi.name, cpi.flags);
11143                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11144                     // This is a singleton provider, but a user besides the
11145                     // default user is asking to initialize a process it runs
11146                     // in...  well, no, it doesn't actually run in this process,
11147                     // it runs in the process of the default user.  Get rid of it.
11148                     providers.remove(i);
11149                     N--;
11150                     i--;
11151                     continue;
11152                 }
11153
11154                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11155                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11156                 if (cpr == null) {
11157                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11158                     mProviderMap.putProviderByClass(comp, cpr);
11159                 }
11160                 if (DEBUG_MU) Slog.v(TAG_MU,
11161                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11162                 app.pubProviders.put(cpi.name, cpr);
11163                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11164                     // Don't add this if it is a platform component that is marked
11165                     // to run in multiple processes, because this is actually
11166                     // part of the framework so doesn't make sense to track as a
11167                     // separate apk in the process.
11168                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11169                             mProcessStats);
11170                 }
11171                 notifyPackageUse(cpi.applicationInfo.packageName,
11172                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11173             }
11174         }
11175         return providers;
11176     }
11177
11178     /**
11179      * Check if the calling UID has a possible chance at accessing the provider
11180      * at the given authority and user.
11181      */
11182     public String checkContentProviderAccess(String authority, int userId) {
11183         if (userId == UserHandle.USER_ALL) {
11184             mContext.enforceCallingOrSelfPermission(
11185                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11186             userId = UserHandle.getCallingUserId();
11187         }
11188
11189         ProviderInfo cpi = null;
11190         try {
11191             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11192                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11193                             | PackageManager.MATCH_DISABLED_COMPONENTS
11194                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11195                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11196                     userId);
11197         } catch (RemoteException ignored) {
11198         }
11199         if (cpi == null) {
11200             return "Failed to find provider " + authority + " for user " + userId
11201                     + "; expected to find a valid ContentProvider for this authority";
11202         }
11203
11204         ProcessRecord r = null;
11205         synchronized (mPidsSelfLocked) {
11206             r = mPidsSelfLocked.get(Binder.getCallingPid());
11207         }
11208         if (r == null) {
11209             return "Failed to find PID " + Binder.getCallingPid();
11210         }
11211
11212         synchronized (this) {
11213             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11214         }
11215     }
11216
11217     /**
11218      * Check if {@link ProcessRecord} has a possible chance at accessing the
11219      * given {@link ProviderInfo}. Final permission checking is always done
11220      * in {@link ContentProvider}.
11221      */
11222     private final String checkContentProviderPermissionLocked(
11223             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11224         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11225         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11226         boolean checkedGrants = false;
11227         if (checkUser) {
11228             // Looking for cross-user grants before enforcing the typical cross-users permissions
11229             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11230             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11231                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11232                     return null;
11233                 }
11234                 checkedGrants = true;
11235             }
11236             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11237                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11238             if (userId != tmpTargetUserId) {
11239                 // When we actually went to determine the final targer user ID, this ended
11240                 // up different than our initial check for the authority.  This is because
11241                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11242                 // SELF.  So we need to re-check the grants again.
11243                 checkedGrants = false;
11244             }
11245         }
11246         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11247                 cpi.applicationInfo.uid, cpi.exported)
11248                 == PackageManager.PERMISSION_GRANTED) {
11249             return null;
11250         }
11251         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11252                 cpi.applicationInfo.uid, cpi.exported)
11253                 == PackageManager.PERMISSION_GRANTED) {
11254             return null;
11255         }
11256
11257         PathPermission[] pps = cpi.pathPermissions;
11258         if (pps != null) {
11259             int i = pps.length;
11260             while (i > 0) {
11261                 i--;
11262                 PathPermission pp = pps[i];
11263                 String pprperm = pp.getReadPermission();
11264                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11265                         cpi.applicationInfo.uid, cpi.exported)
11266                         == PackageManager.PERMISSION_GRANTED) {
11267                     return null;
11268                 }
11269                 String ppwperm = pp.getWritePermission();
11270                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11271                         cpi.applicationInfo.uid, cpi.exported)
11272                         == PackageManager.PERMISSION_GRANTED) {
11273                     return null;
11274                 }
11275             }
11276         }
11277         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11278             return null;
11279         }
11280
11281         final String suffix;
11282         if (!cpi.exported) {
11283             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11284         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11285             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11286         } else {
11287             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11288         }
11289         final String msg = "Permission Denial: opening provider " + cpi.name
11290                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11291                 + ", uid=" + callingUid + ")" + suffix;
11292         Slog.w(TAG, msg);
11293         return msg;
11294     }
11295
11296     /**
11297      * Returns if the ContentProvider has granted a uri to callingUid
11298      */
11299     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11300         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11301         if (perms != null) {
11302             for (int i=perms.size()-1; i>=0; i--) {
11303                 GrantUri grantUri = perms.keyAt(i);
11304                 if (grantUri.sourceUserId == userId || !checkUser) {
11305                     if (matchesProvider(grantUri.uri, cpi)) {
11306                         return true;
11307                     }
11308                 }
11309             }
11310         }
11311         return false;
11312     }
11313
11314     /**
11315      * Returns true if the uri authority is one of the authorities specified in the provider.
11316      */
11317     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11318         String uriAuth = uri.getAuthority();
11319         String cpiAuth = cpi.authority;
11320         if (cpiAuth.indexOf(';') == -1) {
11321             return cpiAuth.equals(uriAuth);
11322         }
11323         String[] cpiAuths = cpiAuth.split(";");
11324         int length = cpiAuths.length;
11325         for (int i = 0; i < length; i++) {
11326             if (cpiAuths[i].equals(uriAuth)) return true;
11327         }
11328         return false;
11329     }
11330
11331     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11332             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11333         if (r != null) {
11334             for (int i=0; i<r.conProviders.size(); i++) {
11335                 ContentProviderConnection conn = r.conProviders.get(i);
11336                 if (conn.provider == cpr) {
11337                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11338                             "Adding provider requested by "
11339                             + r.processName + " from process "
11340                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11341                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11342                     if (stable) {
11343                         conn.stableCount++;
11344                         conn.numStableIncs++;
11345                     } else {
11346                         conn.unstableCount++;
11347                         conn.numUnstableIncs++;
11348                     }
11349                     return conn;
11350                 }
11351             }
11352             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11353             if (stable) {
11354                 conn.stableCount = 1;
11355                 conn.numStableIncs = 1;
11356             } else {
11357                 conn.unstableCount = 1;
11358                 conn.numUnstableIncs = 1;
11359             }
11360             cpr.connections.add(conn);
11361             r.conProviders.add(conn);
11362             startAssociationLocked(r.uid, r.processName, r.curProcState,
11363                     cpr.uid, cpr.name, cpr.info.processName);
11364             return conn;
11365         }
11366         cpr.addExternalProcessHandleLocked(externalProcessToken);
11367         return null;
11368     }
11369
11370     boolean decProviderCountLocked(ContentProviderConnection conn,
11371             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11372         if (conn != null) {
11373             cpr = conn.provider;
11374             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11375                     "Removing provider requested by "
11376                     + conn.client.processName + " from process "
11377                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11378                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11379             if (stable) {
11380                 conn.stableCount--;
11381             } else {
11382                 conn.unstableCount--;
11383             }
11384             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11385                 cpr.connections.remove(conn);
11386                 conn.client.conProviders.remove(conn);
11387                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11388                     // The client is more important than last activity -- note the time this
11389                     // is happening, so we keep the old provider process around a bit as last
11390                     // activity to avoid thrashing it.
11391                     if (cpr.proc != null) {
11392                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11393                     }
11394                 }
11395                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11396                 return true;
11397             }
11398             return false;
11399         }
11400         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11401         return false;
11402     }
11403
11404     private void checkTime(long startTime, String where) {
11405         long now = SystemClock.uptimeMillis();
11406         if ((now-startTime) > 50) {
11407             // If we are taking more than 50ms, log about it.
11408             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11409         }
11410     }
11411
11412     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11413             PROC_SPACE_TERM,
11414             PROC_SPACE_TERM|PROC_PARENS,
11415             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11416     };
11417
11418     private final long[] mProcessStateStatsLongs = new long[1];
11419
11420     boolean isProcessAliveLocked(ProcessRecord proc) {
11421         if (proc.procStatFile == null) {
11422             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11423         }
11424         mProcessStateStatsLongs[0] = 0;
11425         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11426                 mProcessStateStatsLongs, null)) {
11427             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11428             return false;
11429         }
11430         final long state = mProcessStateStatsLongs[0];
11431         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11432                 + (char)state);
11433         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11434     }
11435
11436     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11437             String name, IBinder token, boolean stable, int userId) {
11438         ContentProviderRecord cpr;
11439         ContentProviderConnection conn = null;
11440         ProviderInfo cpi = null;
11441
11442         synchronized(this) {
11443             long startTime = SystemClock.uptimeMillis();
11444
11445             ProcessRecord r = null;
11446             if (caller != null) {
11447                 r = getRecordForAppLocked(caller);
11448                 if (r == null) {
11449                     throw new SecurityException(
11450                             "Unable to find app for caller " + caller
11451                           + " (pid=" + Binder.getCallingPid()
11452                           + ") when getting content provider " + name);
11453                 }
11454             }
11455
11456             boolean checkCrossUser = true;
11457
11458             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11459
11460             // First check if this content provider has been published...
11461             cpr = mProviderMap.getProviderByName(name, userId);
11462             // If that didn't work, check if it exists for user 0 and then
11463             // verify that it's a singleton provider before using it.
11464             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11465                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11466                 if (cpr != null) {
11467                     cpi = cpr.info;
11468                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11469                             cpi.name, cpi.flags)
11470                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11471                         userId = UserHandle.USER_SYSTEM;
11472                         checkCrossUser = false;
11473                     } else {
11474                         cpr = null;
11475                         cpi = null;
11476                     }
11477                 }
11478             }
11479
11480             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11481             if (providerRunning) {
11482                 cpi = cpr.info;
11483                 String msg;
11484                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11485                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11486                         != null) {
11487                     throw new SecurityException(msg);
11488                 }
11489                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11490
11491                 if (r != null && cpr.canRunHere(r)) {
11492                     // This provider has been published or is in the process
11493                     // of being published...  but it is also allowed to run
11494                     // in the caller's process, so don't make a connection
11495                     // and just let the caller instantiate its own instance.
11496                     ContentProviderHolder holder = cpr.newHolder(null);
11497                     // don't give caller the provider object, it needs
11498                     // to make its own.
11499                     holder.provider = null;
11500                     return holder;
11501                 }
11502                 // Don't expose providers between normal apps and instant apps
11503                 try {
11504                     if (AppGlobals.getPackageManager()
11505                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11506                         return null;
11507                     }
11508                 } catch (RemoteException e) {
11509                 }
11510
11511                 final long origId = Binder.clearCallingIdentity();
11512
11513                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11514
11515                 // In this case the provider instance already exists, so we can
11516                 // return it right away.
11517                 conn = incProviderCountLocked(r, cpr, token, stable);
11518                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11519                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11520                         // If this is a perceptible app accessing the provider,
11521                         // make sure to count it as being accessed and thus
11522                         // back up on the LRU list.  This is good because
11523                         // content providers are often expensive to start.
11524                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11525                         updateLruProcessLocked(cpr.proc, false, null);
11526                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11527                     }
11528                 }
11529
11530                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11531                 final int verifiedAdj = cpr.proc.verifiedAdj;
11532                 boolean success = updateOomAdjLocked(cpr.proc, true);
11533                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11534                 // if the process has been successfully adjusted.  So to reduce races with
11535                 // it, we will check whether the process still exists.  Note that this doesn't
11536                 // completely get rid of races with LMK killing the process, but should make
11537                 // them much smaller.
11538                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11539                     success = false;
11540                 }
11541                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11542                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11543                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11544                 // NOTE: there is still a race here where a signal could be
11545                 // pending on the process even though we managed to update its
11546                 // adj level.  Not sure what to do about this, but at least
11547                 // the race is now smaller.
11548                 if (!success) {
11549                     // Uh oh...  it looks like the provider's process
11550                     // has been killed on us.  We need to wait for a new
11551                     // process to be started, and make sure its death
11552                     // doesn't kill our process.
11553                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11554                             + " is crashing; detaching " + r);
11555                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11556                     checkTime(startTime, "getContentProviderImpl: before appDied");
11557                     appDiedLocked(cpr.proc);
11558                     checkTime(startTime, "getContentProviderImpl: after appDied");
11559                     if (!lastRef) {
11560                         // This wasn't the last ref our process had on
11561                         // the provider...  we have now been killed, bail.
11562                         return null;
11563                     }
11564                     providerRunning = false;
11565                     conn = null;
11566                 } else {
11567                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11568                 }
11569
11570                 Binder.restoreCallingIdentity(origId);
11571             }
11572
11573             if (!providerRunning) {
11574                 try {
11575                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11576                     cpi = AppGlobals.getPackageManager().
11577                         resolveContentProvider(name,
11578                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11579                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11580                 } catch (RemoteException ex) {
11581                 }
11582                 if (cpi == null) {
11583                     return null;
11584                 }
11585                 // If the provider is a singleton AND
11586                 // (it's a call within the same user || the provider is a
11587                 // privileged app)
11588                 // Then allow connecting to the singleton provider
11589                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11590                         cpi.name, cpi.flags)
11591                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11592                 if (singleton) {
11593                     userId = UserHandle.USER_SYSTEM;
11594                 }
11595                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11596                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11597
11598                 String msg;
11599                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11600                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11601                         != null) {
11602                     throw new SecurityException(msg);
11603                 }
11604                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11605
11606                 if (!mProcessesReady
11607                         && !cpi.processName.equals("system")) {
11608                     // If this content provider does not run in the system
11609                     // process, and the system is not yet ready to run other
11610                     // processes, then fail fast instead of hanging.
11611                     throw new IllegalArgumentException(
11612                             "Attempt to launch content provider before system ready");
11613                 }
11614
11615                 // Make sure that the user who owns this provider is running.  If not,
11616                 // we don't want to allow it to run.
11617                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11618                     Slog.w(TAG, "Unable to launch app "
11619                             + cpi.applicationInfo.packageName + "/"
11620                             + cpi.applicationInfo.uid + " for provider "
11621                             + name + ": user " + userId + " is stopped");
11622                     return null;
11623                 }
11624
11625                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11626                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11627                 cpr = mProviderMap.getProviderByClass(comp, userId);
11628                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11629                 final boolean firstClass = cpr == null;
11630                 if (firstClass) {
11631                     final long ident = Binder.clearCallingIdentity();
11632
11633                     // If permissions need a review before any of the app components can run,
11634                     // we return no provider and launch a review activity if the calling app
11635                     // is in the foreground.
11636                     if (mPermissionReviewRequired) {
11637                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11638                             return null;
11639                         }
11640                     }
11641
11642                     try {
11643                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11644                         ApplicationInfo ai =
11645                             AppGlobals.getPackageManager().
11646                                 getApplicationInfo(
11647                                         cpi.applicationInfo.packageName,
11648                                         STOCK_PM_FLAGS, userId);
11649                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11650                         if (ai == null) {
11651                             Slog.w(TAG, "No package info for content provider "
11652                                     + cpi.name);
11653                             return null;
11654                         }
11655                         ai = getAppInfoForUser(ai, userId);
11656                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11657                     } catch (RemoteException ex) {
11658                         // pm is in same process, this will never happen.
11659                     } finally {
11660                         Binder.restoreCallingIdentity(ident);
11661                     }
11662                 }
11663
11664                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11665
11666                 if (r != null && cpr.canRunHere(r)) {
11667                     // If this is a multiprocess provider, then just return its
11668                     // info and allow the caller to instantiate it.  Only do
11669                     // this if the provider is the same user as the caller's
11670                     // process, or can run as root (so can be in any process).
11671                     return cpr.newHolder(null);
11672                 }
11673
11674                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11675                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11676                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11677
11678                 // This is single process, and our app is now connecting to it.
11679                 // See if we are already in the process of launching this
11680                 // provider.
11681                 final int N = mLaunchingProviders.size();
11682                 int i;
11683                 for (i = 0; i < N; i++) {
11684                     if (mLaunchingProviders.get(i) == cpr) {
11685                         break;
11686                     }
11687                 }
11688
11689                 // If the provider is not already being launched, then get it
11690                 // started.
11691                 if (i >= N) {
11692                     final long origId = Binder.clearCallingIdentity();
11693
11694                     try {
11695                         // Content provider is now in use, its package can't be stopped.
11696                         try {
11697                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11698                             AppGlobals.getPackageManager().setPackageStoppedState(
11699                                     cpr.appInfo.packageName, false, userId);
11700                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11701                         } catch (RemoteException e) {
11702                         } catch (IllegalArgumentException e) {
11703                             Slog.w(TAG, "Failed trying to unstop package "
11704                                     + cpr.appInfo.packageName + ": " + e);
11705                         }
11706
11707                         // Use existing process if already started
11708                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11709                         ProcessRecord proc = getProcessRecordLocked(
11710                                 cpi.processName, cpr.appInfo.uid, false);
11711                         if (proc != null && proc.thread != null && !proc.killed) {
11712                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11713                                     "Installing in existing process " + proc);
11714                             if (!proc.pubProviders.containsKey(cpi.name)) {
11715                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11716                                 proc.pubProviders.put(cpi.name, cpr);
11717                                 try {
11718                                     proc.thread.scheduleInstallProvider(cpi);
11719                                 } catch (RemoteException e) {
11720                                 }
11721                             }
11722                         } else {
11723                             checkTime(startTime, "getContentProviderImpl: before start process");
11724                             proc = startProcessLocked(cpi.processName,
11725                                     cpr.appInfo, false, 0, "content provider",
11726                                     new ComponentName(cpi.applicationInfo.packageName,
11727                                             cpi.name), false, false, false);
11728                             checkTime(startTime, "getContentProviderImpl: after start process");
11729                             if (proc == null) {
11730                                 Slog.w(TAG, "Unable to launch app "
11731                                         + cpi.applicationInfo.packageName + "/"
11732                                         + cpi.applicationInfo.uid + " for provider "
11733                                         + name + ": process is bad");
11734                                 return null;
11735                             }
11736                         }
11737                         cpr.launchingApp = proc;
11738                         mLaunchingProviders.add(cpr);
11739                     } finally {
11740                         Binder.restoreCallingIdentity(origId);
11741                     }
11742                 }
11743
11744                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11745
11746                 // Make sure the provider is published (the same provider class
11747                 // may be published under multiple names).
11748                 if (firstClass) {
11749                     mProviderMap.putProviderByClass(comp, cpr);
11750                 }
11751
11752                 mProviderMap.putProviderByName(name, cpr);
11753                 conn = incProviderCountLocked(r, cpr, token, stable);
11754                 if (conn != null) {
11755                     conn.waiting = true;
11756                 }
11757             }
11758             checkTime(startTime, "getContentProviderImpl: done!");
11759
11760             grantEphemeralAccessLocked(userId, null /*intent*/,
11761                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11762         }
11763
11764         // Wait for the provider to be published...
11765         synchronized (cpr) {
11766             while (cpr.provider == null) {
11767                 if (cpr.launchingApp == null) {
11768                     Slog.w(TAG, "Unable to launch app "
11769                             + cpi.applicationInfo.packageName + "/"
11770                             + cpi.applicationInfo.uid + " for provider "
11771                             + name + ": launching app became null");
11772                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11773                             UserHandle.getUserId(cpi.applicationInfo.uid),
11774                             cpi.applicationInfo.packageName,
11775                             cpi.applicationInfo.uid, name);
11776                     return null;
11777                 }
11778                 try {
11779                     if (DEBUG_MU) Slog.v(TAG_MU,
11780                             "Waiting to start provider " + cpr
11781                             + " launchingApp=" + cpr.launchingApp);
11782                     if (conn != null) {
11783                         conn.waiting = true;
11784                     }
11785                     cpr.wait();
11786                 } catch (InterruptedException ex) {
11787                 } finally {
11788                     if (conn != null) {
11789                         conn.waiting = false;
11790                     }
11791                 }
11792             }
11793         }
11794         return cpr != null ? cpr.newHolder(conn) : null;
11795     }
11796
11797     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11798             ProcessRecord r, final int userId) {
11799         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11800                 cpi.packageName, userId)) {
11801
11802             final boolean callerForeground = r == null || r.setSchedGroup
11803                     != ProcessList.SCHED_GROUP_BACKGROUND;
11804
11805             // Show a permission review UI only for starting from a foreground app
11806             if (!callerForeground) {
11807                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11808                         + cpi.packageName + " requires a permissions review");
11809                 return false;
11810             }
11811
11812             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11813             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11814                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11815             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11816
11817             if (DEBUG_PERMISSIONS_REVIEW) {
11818                 Slog.i(TAG, "u" + userId + " Launching permission review "
11819                         + "for package " + cpi.packageName);
11820             }
11821
11822             final UserHandle userHandle = new UserHandle(userId);
11823             mHandler.post(new Runnable() {
11824                 @Override
11825                 public void run() {
11826                     mContext.startActivityAsUser(intent, userHandle);
11827                 }
11828             });
11829
11830             return false;
11831         }
11832
11833         return true;
11834     }
11835
11836     PackageManagerInternal getPackageManagerInternalLocked() {
11837         if (mPackageManagerInt == null) {
11838             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11839         }
11840         return mPackageManagerInt;
11841     }
11842
11843     @Override
11844     public final ContentProviderHolder getContentProvider(
11845             IApplicationThread caller, String name, int userId, boolean stable) {
11846         enforceNotIsolatedCaller("getContentProvider");
11847         if (caller == null) {
11848             String msg = "null IApplicationThread when getting content provider "
11849                     + name;
11850             Slog.w(TAG, msg);
11851             throw new SecurityException(msg);
11852         }
11853         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11854         // with cross-user grant.
11855         return getContentProviderImpl(caller, name, null, stable, userId);
11856     }
11857
11858     public ContentProviderHolder getContentProviderExternal(
11859             String name, int userId, IBinder token) {
11860         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11861             "Do not have permission in call getContentProviderExternal()");
11862         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11863                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11864         return getContentProviderExternalUnchecked(name, token, userId);
11865     }
11866
11867     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11868             IBinder token, int userId) {
11869         return getContentProviderImpl(null, name, token, true, userId);
11870     }
11871
11872     /**
11873      * Drop a content provider from a ProcessRecord's bookkeeping
11874      */
11875     public void removeContentProvider(IBinder connection, boolean stable) {
11876         enforceNotIsolatedCaller("removeContentProvider");
11877         long ident = Binder.clearCallingIdentity();
11878         try {
11879             synchronized (this) {
11880                 ContentProviderConnection conn;
11881                 try {
11882                     conn = (ContentProviderConnection)connection;
11883                 } catch (ClassCastException e) {
11884                     String msg ="removeContentProvider: " + connection
11885                             + " not a ContentProviderConnection";
11886                     Slog.w(TAG, msg);
11887                     throw new IllegalArgumentException(msg);
11888                 }
11889                 if (conn == null) {
11890                     throw new NullPointerException("connection is null");
11891                 }
11892                 if (decProviderCountLocked(conn, null, null, stable)) {
11893                     updateOomAdjLocked();
11894                 }
11895             }
11896         } finally {
11897             Binder.restoreCallingIdentity(ident);
11898         }
11899     }
11900
11901     public void removeContentProviderExternal(String name, IBinder token) {
11902         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11903             "Do not have permission in call removeContentProviderExternal()");
11904         int userId = UserHandle.getCallingUserId();
11905         long ident = Binder.clearCallingIdentity();
11906         try {
11907             removeContentProviderExternalUnchecked(name, token, userId);
11908         } finally {
11909             Binder.restoreCallingIdentity(ident);
11910         }
11911     }
11912
11913     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11914         synchronized (this) {
11915             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11916             if(cpr == null) {
11917                 //remove from mProvidersByClass
11918                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11919                 return;
11920             }
11921
11922             //update content provider record entry info
11923             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11924             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11925             if (localCpr.hasExternalProcessHandles()) {
11926                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11927                     updateOomAdjLocked();
11928                 } else {
11929                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11930                             + " with no external reference for token: "
11931                             + token + ".");
11932                 }
11933             } else {
11934                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11935                         + " with no external references.");
11936             }
11937         }
11938     }
11939
11940     public final void publishContentProviders(IApplicationThread caller,
11941             List<ContentProviderHolder> providers) {
11942         if (providers == null) {
11943             return;
11944         }
11945
11946         enforceNotIsolatedCaller("publishContentProviders");
11947         synchronized (this) {
11948             final ProcessRecord r = getRecordForAppLocked(caller);
11949             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11950             if (r == null) {
11951                 throw new SecurityException(
11952                         "Unable to find app for caller " + caller
11953                       + " (pid=" + Binder.getCallingPid()
11954                       + ") when publishing content providers");
11955             }
11956
11957             final long origId = Binder.clearCallingIdentity();
11958
11959             final int N = providers.size();
11960             for (int i = 0; i < N; i++) {
11961                 ContentProviderHolder src = providers.get(i);
11962                 if (src == null || src.info == null || src.provider == null) {
11963                     continue;
11964                 }
11965                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11966                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11967                 if (dst != null) {
11968                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11969                     mProviderMap.putProviderByClass(comp, dst);
11970                     String names[] = dst.info.authority.split(";");
11971                     for (int j = 0; j < names.length; j++) {
11972                         mProviderMap.putProviderByName(names[j], dst);
11973                     }
11974
11975                     int launchingCount = mLaunchingProviders.size();
11976                     int j;
11977                     boolean wasInLaunchingProviders = false;
11978                     for (j = 0; j < launchingCount; j++) {
11979                         if (mLaunchingProviders.get(j) == dst) {
11980                             mLaunchingProviders.remove(j);
11981                             wasInLaunchingProviders = true;
11982                             j--;
11983                             launchingCount--;
11984                         }
11985                     }
11986                     if (wasInLaunchingProviders) {
11987                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11988                     }
11989                     synchronized (dst) {
11990                         dst.provider = src.provider;
11991                         dst.proc = r;
11992                         dst.notifyAll();
11993                     }
11994                     updateOomAdjLocked(r, true);
11995                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11996                             src.info.authority);
11997                 }
11998             }
11999
12000             Binder.restoreCallingIdentity(origId);
12001         }
12002     }
12003
12004     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12005         ContentProviderConnection conn;
12006         try {
12007             conn = (ContentProviderConnection)connection;
12008         } catch (ClassCastException e) {
12009             String msg ="refContentProvider: " + connection
12010                     + " not a ContentProviderConnection";
12011             Slog.w(TAG, msg);
12012             throw new IllegalArgumentException(msg);
12013         }
12014         if (conn == null) {
12015             throw new NullPointerException("connection is null");
12016         }
12017
12018         synchronized (this) {
12019             if (stable > 0) {
12020                 conn.numStableIncs += stable;
12021             }
12022             stable = conn.stableCount + stable;
12023             if (stable < 0) {
12024                 throw new IllegalStateException("stableCount < 0: " + stable);
12025             }
12026
12027             if (unstable > 0) {
12028                 conn.numUnstableIncs += unstable;
12029             }
12030             unstable = conn.unstableCount + unstable;
12031             if (unstable < 0) {
12032                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12033             }
12034
12035             if ((stable+unstable) <= 0) {
12036                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12037                         + stable + " unstable=" + unstable);
12038             }
12039             conn.stableCount = stable;
12040             conn.unstableCount = unstable;
12041             return !conn.dead;
12042         }
12043     }
12044
12045     public void unstableProviderDied(IBinder connection) {
12046         ContentProviderConnection conn;
12047         try {
12048             conn = (ContentProviderConnection)connection;
12049         } catch (ClassCastException e) {
12050             String msg ="refContentProvider: " + connection
12051                     + " not a ContentProviderConnection";
12052             Slog.w(TAG, msg);
12053             throw new IllegalArgumentException(msg);
12054         }
12055         if (conn == null) {
12056             throw new NullPointerException("connection is null");
12057         }
12058
12059         // Safely retrieve the content provider associated with the connection.
12060         IContentProvider provider;
12061         synchronized (this) {
12062             provider = conn.provider.provider;
12063         }
12064
12065         if (provider == null) {
12066             // Um, yeah, we're way ahead of you.
12067             return;
12068         }
12069
12070         // Make sure the caller is being honest with us.
12071         if (provider.asBinder().pingBinder()) {
12072             // Er, no, still looks good to us.
12073             synchronized (this) {
12074                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12075                         + " says " + conn + " died, but we don't agree");
12076                 return;
12077             }
12078         }
12079
12080         // Well look at that!  It's dead!
12081         synchronized (this) {
12082             if (conn.provider.provider != provider) {
12083                 // But something changed...  good enough.
12084                 return;
12085             }
12086
12087             ProcessRecord proc = conn.provider.proc;
12088             if (proc == null || proc.thread == null) {
12089                 // Seems like the process is already cleaned up.
12090                 return;
12091             }
12092
12093             // As far as we're concerned, this is just like receiving a
12094             // death notification...  just a bit prematurely.
12095             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12096                     + ") early provider death");
12097             final long ident = Binder.clearCallingIdentity();
12098             try {
12099                 appDiedLocked(proc);
12100             } finally {
12101                 Binder.restoreCallingIdentity(ident);
12102             }
12103         }
12104     }
12105
12106     @Override
12107     public void appNotRespondingViaProvider(IBinder connection) {
12108         enforceCallingPermission(
12109                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12110
12111         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12112         if (conn == null) {
12113             Slog.w(TAG, "ContentProviderConnection is null");
12114             return;
12115         }
12116
12117         final ProcessRecord host = conn.provider.proc;
12118         if (host == null) {
12119             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12120             return;
12121         }
12122
12123         mHandler.post(new Runnable() {
12124             @Override
12125             public void run() {
12126                 mAppErrors.appNotResponding(host, null, null, false,
12127                         "ContentProvider not responding");
12128             }
12129         });
12130     }
12131
12132     public final void installSystemProviders() {
12133         List<ProviderInfo> providers;
12134         synchronized (this) {
12135             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12136             providers = generateApplicationProvidersLocked(app);
12137             if (providers != null) {
12138                 for (int i=providers.size()-1; i>=0; i--) {
12139                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12140                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12141                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12142                                 + ": not system .apk");
12143                         providers.remove(i);
12144                     }
12145                 }
12146             }
12147         }
12148         if (providers != null) {
12149             mSystemThread.installSystemProviders(providers);
12150         }
12151
12152         mConstants.start(mContext.getContentResolver());
12153         mCoreSettingsObserver = new CoreSettingsObserver(this);
12154         mFontScaleSettingObserver = new FontScaleSettingObserver();
12155
12156         // Now that the settings provider is published we can consider sending
12157         // in a rescue party.
12158         RescueParty.onSettingsProviderPublished(mContext);
12159
12160         //mUsageStatsService.monitorPackages();
12161     }
12162
12163     private void startPersistentApps(int matchFlags) {
12164         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12165
12166         synchronized (this) {
12167             try {
12168                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12169                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12170                 for (ApplicationInfo app : apps) {
12171                     if (!"android".equals(app.packageName)) {
12172                         addAppLocked(app, null, false, null /* ABI override */);
12173                     }
12174                 }
12175             } catch (RemoteException ex) {
12176             }
12177         }
12178     }
12179
12180     /**
12181      * When a user is unlocked, we need to install encryption-unaware providers
12182      * belonging to any running apps.
12183      */
12184     private void installEncryptionUnawareProviders(int userId) {
12185         // We're only interested in providers that are encryption unaware, and
12186         // we don't care about uninstalled apps, since there's no way they're
12187         // running at this point.
12188         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12189
12190         synchronized (this) {
12191             final int NP = mProcessNames.getMap().size();
12192             for (int ip = 0; ip < NP; ip++) {
12193                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12194                 final int NA = apps.size();
12195                 for (int ia = 0; ia < NA; ia++) {
12196                     final ProcessRecord app = apps.valueAt(ia);
12197                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12198
12199                     final int NG = app.pkgList.size();
12200                     for (int ig = 0; ig < NG; ig++) {
12201                         try {
12202                             final String pkgName = app.pkgList.keyAt(ig);
12203                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12204                                     .getPackageInfo(pkgName, matchFlags, userId);
12205                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12206                                 for (ProviderInfo pi : pkgInfo.providers) {
12207                                     // TODO: keep in sync with generateApplicationProvidersLocked
12208                                     final boolean processMatch = Objects.equals(pi.processName,
12209                                             app.processName) || pi.multiprocess;
12210                                     final boolean userMatch = isSingleton(pi.processName,
12211                                             pi.applicationInfo, pi.name, pi.flags)
12212                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12213                                     if (processMatch && userMatch) {
12214                                         Log.v(TAG, "Installing " + pi);
12215                                         app.thread.scheduleInstallProvider(pi);
12216                                     } else {
12217                                         Log.v(TAG, "Skipping " + pi);
12218                                     }
12219                                 }
12220                             }
12221                         } catch (RemoteException ignored) {
12222                         }
12223                     }
12224                 }
12225             }
12226         }
12227     }
12228
12229     /**
12230      * Allows apps to retrieve the MIME type of a URI.
12231      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12232      * users, then it does not need permission to access the ContentProvider.
12233      * Either, it needs cross-user uri grants.
12234      *
12235      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12236      *
12237      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12238      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12239      */
12240     public String getProviderMimeType(Uri uri, int userId) {
12241         enforceNotIsolatedCaller("getProviderMimeType");
12242         final String name = uri.getAuthority();
12243         int callingUid = Binder.getCallingUid();
12244         int callingPid = Binder.getCallingPid();
12245         long ident = 0;
12246         boolean clearedIdentity = false;
12247         synchronized (this) {
12248             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12249         }
12250         if (canClearIdentity(callingPid, callingUid, userId)) {
12251             clearedIdentity = true;
12252             ident = Binder.clearCallingIdentity();
12253         }
12254         ContentProviderHolder holder = null;
12255         try {
12256             holder = getContentProviderExternalUnchecked(name, null, userId);
12257             if (holder != null) {
12258                 return holder.provider.getType(uri);
12259             }
12260         } catch (RemoteException e) {
12261             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12262             return null;
12263         } catch (Exception e) {
12264             Log.w(TAG, "Exception while determining type of " + uri, e);
12265             return null;
12266         } finally {
12267             // We need to clear the identity to call removeContentProviderExternalUnchecked
12268             if (!clearedIdentity) {
12269                 ident = Binder.clearCallingIdentity();
12270             }
12271             try {
12272                 if (holder != null) {
12273                     removeContentProviderExternalUnchecked(name, null, userId);
12274                 }
12275             } finally {
12276                 Binder.restoreCallingIdentity(ident);
12277             }
12278         }
12279
12280         return null;
12281     }
12282
12283     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12284         if (UserHandle.getUserId(callingUid) == userId) {
12285             return true;
12286         }
12287         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12288                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12289                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12290                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12291                 return true;
12292         }
12293         return false;
12294     }
12295
12296     // =========================================================
12297     // GLOBAL MANAGEMENT
12298     // =========================================================
12299
12300     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12301             boolean isolated, int isolatedUid) {
12302         String proc = customProcess != null ? customProcess : info.processName;
12303         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12304         final int userId = UserHandle.getUserId(info.uid);
12305         int uid = info.uid;
12306         if (isolated) {
12307             if (isolatedUid == 0) {
12308                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12309                 while (true) {
12310                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12311                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12312                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12313                     }
12314                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12315                     mNextIsolatedProcessUid++;
12316                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12317                         // No process for this uid, use it.
12318                         break;
12319                     }
12320                     stepsLeft--;
12321                     if (stepsLeft <= 0) {
12322                         return null;
12323                     }
12324                 }
12325             } else {
12326                 // Special case for startIsolatedProcess (internal only), where
12327                 // the uid of the isolated process is specified by the caller.
12328                 uid = isolatedUid;
12329             }
12330             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12331
12332             // Register the isolated UID with this application so BatteryStats knows to
12333             // attribute resource usage to the application.
12334             //
12335             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12336             // about the process state of the isolated UID *before* it is registered with the
12337             // owning application.
12338             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12339         }
12340         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12341         if (!mBooted && !mBooting
12342                 && userId == UserHandle.USER_SYSTEM
12343                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12344             r.persistent = true;
12345             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12346         }
12347         addProcessNameLocked(r);
12348         return r;
12349     }
12350
12351     private boolean uidOnBackgroundWhitelist(final int uid) {
12352         final int appId = UserHandle.getAppId(uid);
12353         final int[] whitelist = mBackgroundAppIdWhitelist;
12354         final int N = whitelist.length;
12355         for (int i = 0; i < N; i++) {
12356             if (appId == whitelist[i]) {
12357                 return true;
12358             }
12359         }
12360         return false;
12361     }
12362
12363     @Override
12364     public void backgroundWhitelistUid(final int uid) {
12365         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12366             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12367         }
12368
12369         if (DEBUG_BACKGROUND_CHECK) {
12370             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12371         }
12372         synchronized (this) {
12373             final int N = mBackgroundAppIdWhitelist.length;
12374             int[] newList = new int[N+1];
12375             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12376             newList[N] = UserHandle.getAppId(uid);
12377             mBackgroundAppIdWhitelist = newList;
12378         }
12379     }
12380
12381     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12382             String abiOverride) {
12383         ProcessRecord app;
12384         if (!isolated) {
12385             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12386                     info.uid, true);
12387         } else {
12388             app = null;
12389         }
12390
12391         if (app == null) {
12392             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12393             updateLruProcessLocked(app, false, null);
12394             updateOomAdjLocked();
12395         }
12396
12397         // This package really, really can not be stopped.
12398         try {
12399             AppGlobals.getPackageManager().setPackageStoppedState(
12400                     info.packageName, false, UserHandle.getUserId(app.uid));
12401         } catch (RemoteException e) {
12402         } catch (IllegalArgumentException e) {
12403             Slog.w(TAG, "Failed trying to unstop package "
12404                     + info.packageName + ": " + e);
12405         }
12406
12407         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12408             app.persistent = true;
12409             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12410         }
12411         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12412             mPersistentStartingProcesses.add(app);
12413             startProcessLocked(app, "added application",
12414                     customProcess != null ? customProcess : app.processName, abiOverride,
12415                     null /* entryPoint */, null /* entryPointArgs */);
12416         }
12417
12418         return app;
12419     }
12420
12421     public void unhandledBack() {
12422         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12423                 "unhandledBack()");
12424
12425         synchronized(this) {
12426             final long origId = Binder.clearCallingIdentity();
12427             try {
12428                 getFocusedStack().unhandledBackLocked();
12429             } finally {
12430                 Binder.restoreCallingIdentity(origId);
12431             }
12432         }
12433     }
12434
12435     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12436         enforceNotIsolatedCaller("openContentUri");
12437         final int userId = UserHandle.getCallingUserId();
12438         final Uri uri = Uri.parse(uriString);
12439         String name = uri.getAuthority();
12440         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12441         ParcelFileDescriptor pfd = null;
12442         if (cph != null) {
12443             // We record the binder invoker's uid in thread-local storage before
12444             // going to the content provider to open the file.  Later, in the code
12445             // that handles all permissions checks, we look for this uid and use
12446             // that rather than the Activity Manager's own uid.  The effect is that
12447             // we do the check against the caller's permissions even though it looks
12448             // to the content provider like the Activity Manager itself is making
12449             // the request.
12450             Binder token = new Binder();
12451             sCallerIdentity.set(new Identity(
12452                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12453             try {
12454                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12455             } catch (FileNotFoundException e) {
12456                 // do nothing; pfd will be returned null
12457             } finally {
12458                 // Ensure that whatever happens, we clean up the identity state
12459                 sCallerIdentity.remove();
12460                 // Ensure we're done with the provider.
12461                 removeContentProviderExternalUnchecked(name, null, userId);
12462             }
12463         } else {
12464             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12465         }
12466         return pfd;
12467     }
12468
12469     // Actually is sleeping or shutting down or whatever else in the future
12470     // is an inactive state.
12471     boolean isSleepingOrShuttingDownLocked() {
12472         return isSleepingLocked() || mShuttingDown;
12473     }
12474
12475     boolean isShuttingDownLocked() {
12476         return mShuttingDown;
12477     }
12478
12479     boolean isSleepingLocked() {
12480         return mSleeping;
12481     }
12482
12483     void onWakefulnessChanged(int wakefulness) {
12484         synchronized(this) {
12485             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12486             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12487             mWakefulness = wakefulness;
12488
12489             if (wasAwake != isAwake) {
12490                 // Also update state in a special way for running foreground services UI.
12491                 mServices.updateScreenStateLocked(isAwake);
12492                 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12493                         .sendToTarget();
12494             }
12495         }
12496     }
12497
12498     void finishRunningVoiceLocked() {
12499         if (mRunningVoice != null) {
12500             mRunningVoice = null;
12501             mVoiceWakeLock.release();
12502             updateSleepIfNeededLocked();
12503         }
12504     }
12505
12506     void startTimeTrackingFocusedActivityLocked() {
12507         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12508         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12509             mCurAppTimeTracker.start(resumedActivity.packageName);
12510         }
12511     }
12512
12513     void updateSleepIfNeededLocked() {
12514         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12515         final boolean wasSleeping = mSleeping;
12516
12517         if (!shouldSleep) {
12518             // If wasSleeping is true, we need to wake up activity manager state from when
12519             // we started sleeping. In either case, we need to apply the sleep tokens, which
12520             // will wake up stacks or put them to sleep as appropriate.
12521             if (wasSleeping) {
12522                 mSleeping = false;
12523                 startTimeTrackingFocusedActivityLocked();
12524                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12525                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12526             }
12527             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12528             if (wasSleeping) {
12529                 updateOomAdjLocked();
12530             }
12531         } else if (!mSleeping && shouldSleep) {
12532             mSleeping = true;
12533             if (mCurAppTimeTracker != null) {
12534                 mCurAppTimeTracker.stop();
12535             }
12536             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12537             mStackSupervisor.goingToSleepLocked();
12538             updateOomAdjLocked();
12539         }
12540     }
12541
12542     /** Pokes the task persister. */
12543     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12544         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12545     }
12546
12547     /**
12548      * Notifies all listeners when the pinned stack animation starts.
12549      */
12550     @Override
12551     public void notifyPinnedStackAnimationStarted() {
12552         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12553     }
12554
12555     /**
12556      * Notifies all listeners when the pinned stack animation ends.
12557      */
12558     @Override
12559     public void notifyPinnedStackAnimationEnded() {
12560         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12561     }
12562
12563     @Override
12564     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12565         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12566     }
12567
12568     @Override
12569     public boolean shutdown(int timeout) {
12570         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12571                 != PackageManager.PERMISSION_GRANTED) {
12572             throw new SecurityException("Requires permission "
12573                     + android.Manifest.permission.SHUTDOWN);
12574         }
12575
12576         boolean timedout = false;
12577
12578         synchronized(this) {
12579             mShuttingDown = true;
12580             mStackSupervisor.prepareForShutdownLocked();
12581             updateEventDispatchingLocked();
12582             timedout = mStackSupervisor.shutdownLocked(timeout);
12583         }
12584
12585         mAppOpsService.shutdown();
12586         if (mUsageStatsService != null) {
12587             mUsageStatsService.prepareShutdown();
12588         }
12589         mBatteryStatsService.shutdown();
12590         synchronized (this) {
12591             mProcessStats.shutdownLocked();
12592             notifyTaskPersisterLocked(null, true);
12593         }
12594
12595         return timedout;
12596     }
12597
12598     public final void activitySlept(IBinder token) {
12599         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12600
12601         final long origId = Binder.clearCallingIdentity();
12602
12603         synchronized (this) {
12604             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12605             if (r != null) {
12606                 mStackSupervisor.activitySleptLocked(r);
12607             }
12608         }
12609
12610         Binder.restoreCallingIdentity(origId);
12611     }
12612
12613     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12614         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12615         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12616         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12617             boolean wasRunningVoice = mRunningVoice != null;
12618             mRunningVoice = session;
12619             if (!wasRunningVoice) {
12620                 mVoiceWakeLock.acquire();
12621                 updateSleepIfNeededLocked();
12622             }
12623         }
12624     }
12625
12626     private void updateEventDispatchingLocked() {
12627         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12628     }
12629
12630     @Override
12631     public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12632         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12633                 != PackageManager.PERMISSION_GRANTED) {
12634             throw new SecurityException("Requires permission "
12635                     + android.Manifest.permission.DEVICE_POWER);
12636         }
12637
12638         synchronized(this) {
12639             long ident = Binder.clearCallingIdentity();
12640             try {
12641                 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12642             } finally {
12643                 Binder.restoreCallingIdentity(ident);
12644             }
12645         }
12646
12647         mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12648                 .sendToTarget();
12649     }
12650
12651     @Override
12652     public void notifyLockedProfile(@UserIdInt int userId) {
12653         try {
12654             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12655                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12656             }
12657         } catch (RemoteException ex) {
12658             throw new SecurityException("Fail to check is caller a privileged app", ex);
12659         }
12660
12661         synchronized (this) {
12662             final long ident = Binder.clearCallingIdentity();
12663             try {
12664                 if (mUserController.shouldConfirmCredentials(userId)) {
12665                     if (mKeyguardController.isKeyguardLocked()) {
12666                         // Showing launcher to avoid user entering credential twice.
12667                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12668                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12669                     }
12670                     mStackSupervisor.lockAllProfileTasks(userId);
12671                 }
12672             } finally {
12673                 Binder.restoreCallingIdentity(ident);
12674             }
12675         }
12676     }
12677
12678     @Override
12679     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12680         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12681         synchronized (this) {
12682             final long ident = Binder.clearCallingIdentity();
12683             try {
12684                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12685             } finally {
12686                 Binder.restoreCallingIdentity(ident);
12687             }
12688         }
12689     }
12690
12691     @Override
12692     public void stopAppSwitches() {
12693         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12694                 != PackageManager.PERMISSION_GRANTED) {
12695             throw new SecurityException("viewquires permission "
12696                     + android.Manifest.permission.STOP_APP_SWITCHES);
12697         }
12698
12699         synchronized(this) {
12700             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12701                     + APP_SWITCH_DELAY_TIME;
12702             mDidAppSwitch = false;
12703             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12704             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12705             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12706         }
12707     }
12708
12709     public void resumeAppSwitches() {
12710         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12711                 != PackageManager.PERMISSION_GRANTED) {
12712             throw new SecurityException("Requires permission "
12713                     + android.Manifest.permission.STOP_APP_SWITCHES);
12714         }
12715
12716         synchronized(this) {
12717             // Note that we don't execute any pending app switches... we will
12718             // let those wait until either the timeout, or the next start
12719             // activity request.
12720             mAppSwitchesAllowedTime = 0;
12721         }
12722     }
12723
12724     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12725             int callingPid, int callingUid, String name) {
12726         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12727             return true;
12728         }
12729
12730         int perm = checkComponentPermission(
12731                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12732                 sourceUid, -1, true);
12733         if (perm == PackageManager.PERMISSION_GRANTED) {
12734             return true;
12735         }
12736
12737         // If the actual IPC caller is different from the logical source, then
12738         // also see if they are allowed to control app switches.
12739         if (callingUid != -1 && callingUid != sourceUid) {
12740             perm = checkComponentPermission(
12741                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12742                     callingUid, -1, true);
12743             if (perm == PackageManager.PERMISSION_GRANTED) {
12744                 return true;
12745             }
12746         }
12747
12748         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12749         return false;
12750     }
12751
12752     public void setDebugApp(String packageName, boolean waitForDebugger,
12753             boolean persistent) {
12754         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12755                 "setDebugApp()");
12756
12757         long ident = Binder.clearCallingIdentity();
12758         try {
12759             // Note that this is not really thread safe if there are multiple
12760             // callers into it at the same time, but that's not a situation we
12761             // care about.
12762             if (persistent) {
12763                 final ContentResolver resolver = mContext.getContentResolver();
12764                 Settings.Global.putString(
12765                     resolver, Settings.Global.DEBUG_APP,
12766                     packageName);
12767                 Settings.Global.putInt(
12768                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12769                     waitForDebugger ? 1 : 0);
12770             }
12771
12772             synchronized (this) {
12773                 if (!persistent) {
12774                     mOrigDebugApp = mDebugApp;
12775                     mOrigWaitForDebugger = mWaitForDebugger;
12776                 }
12777                 mDebugApp = packageName;
12778                 mWaitForDebugger = waitForDebugger;
12779                 mDebugTransient = !persistent;
12780                 if (packageName != null) {
12781                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12782                             false, UserHandle.USER_ALL, "set debug app");
12783                 }
12784             }
12785         } finally {
12786             Binder.restoreCallingIdentity(ident);
12787         }
12788     }
12789
12790     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12791         synchronized (this) {
12792             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12793             if (!isDebuggable) {
12794                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12795                     throw new SecurityException("Process not debuggable: " + app.packageName);
12796                 }
12797             }
12798
12799             mTrackAllocationApp = processName;
12800         }
12801     }
12802
12803     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12804         synchronized (this) {
12805             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12806             if (!isDebuggable) {
12807                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12808                     throw new SecurityException("Process not debuggable: " + app.packageName);
12809                 }
12810             }
12811             mProfileApp = processName;
12812
12813             if (mProfilerInfo != null) {
12814                 if (mProfilerInfo.profileFd != null) {
12815                     try {
12816                         mProfilerInfo.profileFd.close();
12817                     } catch (IOException e) {
12818                     }
12819                 }
12820             }
12821             mProfilerInfo = new ProfilerInfo(profilerInfo);
12822             mProfileType = 0;
12823         }
12824     }
12825
12826     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12827         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12828         if (!isDebuggable) {
12829             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12830                 throw new SecurityException("Process not debuggable: " + app.packageName);
12831             }
12832         }
12833         mNativeDebuggingApp = processName;
12834     }
12835
12836     @Override
12837     public void setAlwaysFinish(boolean enabled) {
12838         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12839                 "setAlwaysFinish()");
12840
12841         long ident = Binder.clearCallingIdentity();
12842         try {
12843             Settings.Global.putInt(
12844                     mContext.getContentResolver(),
12845                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12846
12847             synchronized (this) {
12848                 mAlwaysFinishActivities = enabled;
12849             }
12850         } finally {
12851             Binder.restoreCallingIdentity(ident);
12852         }
12853     }
12854
12855     @Override
12856     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12857         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12858                 "setActivityController()");
12859         synchronized (this) {
12860             mController = controller;
12861             mControllerIsAMonkey = imAMonkey;
12862             Watchdog.getInstance().setActivityController(controller);
12863         }
12864     }
12865
12866     @Override
12867     public void setUserIsMonkey(boolean userIsMonkey) {
12868         synchronized (this) {
12869             synchronized (mPidsSelfLocked) {
12870                 final int callingPid = Binder.getCallingPid();
12871                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12872                 if (proc == null) {
12873                     throw new SecurityException("Unknown process: " + callingPid);
12874                 }
12875                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12876                     throw new SecurityException("Only an instrumentation process "
12877                             + "with a UiAutomation can call setUserIsMonkey");
12878                 }
12879             }
12880             mUserIsMonkey = userIsMonkey;
12881         }
12882     }
12883
12884     @Override
12885     public boolean isUserAMonkey() {
12886         synchronized (this) {
12887             // If there is a controller also implies the user is a monkey.
12888             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12889         }
12890     }
12891
12892     /**
12893      * @deprecated This method is only used by a few internal components and it will soon be
12894      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12895      * No new code should be calling it.
12896      */
12897     @Deprecated
12898     @Override
12899     public void requestBugReport(int bugreportType) {
12900         String extraOptions = null;
12901         switch (bugreportType) {
12902             case ActivityManager.BUGREPORT_OPTION_FULL:
12903                 // Default options.
12904                 break;
12905             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12906                 extraOptions = "bugreportplus";
12907                 break;
12908             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12909                 extraOptions = "bugreportremote";
12910                 break;
12911             case ActivityManager.BUGREPORT_OPTION_WEAR:
12912                 extraOptions = "bugreportwear";
12913                 break;
12914             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12915                 extraOptions = "bugreporttelephony";
12916                 break;
12917             default:
12918                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12919                         + bugreportType);
12920         }
12921         // Always log caller, even if it does not have permission to dump.
12922         String type = extraOptions == null ? "bugreport" : extraOptions;
12923         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12924
12925         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12926         if (extraOptions != null) {
12927             SystemProperties.set("dumpstate.options", extraOptions);
12928         }
12929         SystemProperties.set("ctl.start", "bugreport");
12930     }
12931
12932     /**
12933      * @deprecated This method is only used by a few internal components and it will soon be
12934      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12935      * No new code should be calling it.
12936      */
12937     @Deprecated
12938     @Override
12939     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12940
12941         if (!TextUtils.isEmpty(shareTitle)) {
12942             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12943                 String errorStr = "shareTitle should be less than " +
12944                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12945                 throw new IllegalArgumentException(errorStr);
12946             } else {
12947                 if (!TextUtils.isEmpty(shareDescription)) {
12948                     int length;
12949                     try {
12950                         length = shareDescription.getBytes("UTF-8").length;
12951                     } catch (UnsupportedEncodingException e) {
12952                         String errorStr = "shareDescription: UnsupportedEncodingException";
12953                         throw new IllegalArgumentException(errorStr);
12954                     }
12955                     if (length > SystemProperties.PROP_VALUE_MAX) {
12956                         String errorStr = "shareTitle should be less than " +
12957                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12958                         throw new IllegalArgumentException(errorStr);
12959                     } else {
12960                         SystemProperties.set("dumpstate.options.description", shareDescription);
12961                     }
12962                 }
12963                 SystemProperties.set("dumpstate.options.title", shareTitle);
12964             }
12965         }
12966
12967         Slog.d(TAG, "Bugreport notification title " + shareTitle
12968                 + " description " + shareDescription);
12969         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12970     }
12971
12972     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12973         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12974     }
12975
12976     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12977         if (r != null && (r.instr != null || r.usingWrapper)) {
12978             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12979         }
12980         return KEY_DISPATCHING_TIMEOUT;
12981     }
12982
12983     @Override
12984     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12985         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12986                 != PackageManager.PERMISSION_GRANTED) {
12987             throw new SecurityException("Requires permission "
12988                     + android.Manifest.permission.FILTER_EVENTS);
12989         }
12990         ProcessRecord proc;
12991         long timeout;
12992         synchronized (this) {
12993             synchronized (mPidsSelfLocked) {
12994                 proc = mPidsSelfLocked.get(pid);
12995             }
12996             timeout = getInputDispatchingTimeoutLocked(proc);
12997         }
12998
12999         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13000             return -1;
13001         }
13002
13003         return timeout;
13004     }
13005
13006     /**
13007      * Handle input dispatching timeouts.
13008      * Returns whether input dispatching should be aborted or not.
13009      */
13010     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13011             final ActivityRecord activity, final ActivityRecord parent,
13012             final boolean aboveSystem, String reason) {
13013         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13014                 != PackageManager.PERMISSION_GRANTED) {
13015             throw new SecurityException("Requires permission "
13016                     + android.Manifest.permission.FILTER_EVENTS);
13017         }
13018
13019         final String annotation;
13020         if (reason == null) {
13021             annotation = "Input dispatching timed out";
13022         } else {
13023             annotation = "Input dispatching timed out (" + reason + ")";
13024         }
13025
13026         if (proc != null) {
13027             synchronized (this) {
13028                 if (proc.debugging) {
13029                     return false;
13030                 }
13031
13032                 if (proc.instr != null) {
13033                     Bundle info = new Bundle();
13034                     info.putString("shortMsg", "keyDispatchingTimedOut");
13035                     info.putString("longMsg", annotation);
13036                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13037                     return true;
13038                 }
13039             }
13040             mHandler.post(new Runnable() {
13041                 @Override
13042                 public void run() {
13043                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13044                 }
13045             });
13046         }
13047
13048         return true;
13049     }
13050
13051     @Override
13052     public Bundle getAssistContextExtras(int requestType) {
13053         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13054                 null, null, true /* focused */, true /* newSessionId */,
13055                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13056         if (pae == null) {
13057             return null;
13058         }
13059         synchronized (pae) {
13060             while (!pae.haveResult) {
13061                 try {
13062                     pae.wait();
13063                 } catch (InterruptedException e) {
13064                 }
13065             }
13066         }
13067         synchronized (this) {
13068             buildAssistBundleLocked(pae, pae.result);
13069             mPendingAssistExtras.remove(pae);
13070             mUiHandler.removeCallbacks(pae);
13071         }
13072         return pae.extras;
13073     }
13074
13075     @Override
13076     public boolean isAssistDataAllowedOnCurrentActivity() {
13077         int userId;
13078         synchronized (this) {
13079             final ActivityStack focusedStack = getFocusedStack();
13080             if (focusedStack == null || focusedStack.isAssistantStack()) {
13081                 return false;
13082             }
13083
13084             final ActivityRecord activity = focusedStack.topActivity();
13085             if (activity == null) {
13086                 return false;
13087             }
13088             userId = activity.userId;
13089         }
13090         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13091                 Context.DEVICE_POLICY_SERVICE);
13092         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13093     }
13094
13095     @Override
13096     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13097         long ident = Binder.clearCallingIdentity();
13098         try {
13099             synchronized (this) {
13100                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13101                 ActivityRecord top = getFocusedStack().topActivity();
13102                 if (top != caller) {
13103                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13104                             + " is not current top " + top);
13105                     return false;
13106                 }
13107                 if (!top.nowVisible) {
13108                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13109                             + " is not visible");
13110                     return false;
13111                 }
13112             }
13113             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13114                     token);
13115         } finally {
13116             Binder.restoreCallingIdentity(ident);
13117         }
13118     }
13119
13120     @Override
13121     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13122             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13123         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13124                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13125                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13126     }
13127
13128     @Override
13129     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13130             IBinder activityToken, int flags) {
13131         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13132                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13133                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13134     }
13135
13136     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13137             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13138             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13139             int flags) {
13140         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13141                 "enqueueAssistContext()");
13142
13143         synchronized (this) {
13144             ActivityRecord activity = getFocusedStack().topActivity();
13145             if (activity == null) {
13146                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13147                 return null;
13148             }
13149             if (activity.app == null || activity.app.thread == null) {
13150                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13151                 return null;
13152             }
13153             if (focused) {
13154                 if (activityToken != null) {
13155                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13156                     if (activity != caller) {
13157                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13158                                 + " is not current top " + activity);
13159                         return null;
13160                     }
13161                 }
13162             } else {
13163                 activity = ActivityRecord.forTokenLocked(activityToken);
13164                 if (activity == null) {
13165                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13166                             + " couldn't be found");
13167                     return null;
13168                 }
13169                 if (activity.app == null || activity.app.thread == null) {
13170                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13171                     return null;
13172                 }
13173             }
13174
13175             PendingAssistExtras pae;
13176             Bundle extras = new Bundle();
13177             if (args != null) {
13178                 extras.putAll(args);
13179             }
13180             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13181             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13182
13183             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13184                     userHandle);
13185             pae.isHome = activity.isHomeActivity();
13186
13187             // Increment the sessionId if necessary
13188             if (newSessionId) {
13189                 mViSessionId++;
13190             }
13191             try {
13192                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13193                         mViSessionId, flags);
13194                 mPendingAssistExtras.add(pae);
13195                 mUiHandler.postDelayed(pae, timeout);
13196             } catch (RemoteException e) {
13197                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13198                 return null;
13199             }
13200             return pae;
13201         }
13202     }
13203
13204     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13205         IResultReceiver receiver;
13206         synchronized (this) {
13207             mPendingAssistExtras.remove(pae);
13208             receiver = pae.receiver;
13209         }
13210         if (receiver != null) {
13211             // Caller wants result sent back to them.
13212             Bundle sendBundle = new Bundle();
13213             // At least return the receiver extras
13214             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13215                     pae.receiverExtras);
13216             try {
13217                 pae.receiver.send(0, sendBundle);
13218             } catch (RemoteException e) {
13219             }
13220         }
13221     }
13222
13223     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13224         if (result != null) {
13225             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13226         }
13227         if (pae.hint != null) {
13228             pae.extras.putBoolean(pae.hint, true);
13229         }
13230     }
13231
13232     /** Called from an app when assist data is ready. */
13233     @Override
13234     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13235             AssistContent content, Uri referrer) {
13236         PendingAssistExtras pae = (PendingAssistExtras)token;
13237         synchronized (pae) {
13238             pae.result = extras;
13239             pae.structure = structure;
13240             pae.content = content;
13241             if (referrer != null) {
13242                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13243             }
13244             if (structure != null) {
13245                 structure.setHomeActivity(pae.isHome);
13246             }
13247             pae.haveResult = true;
13248             pae.notifyAll();
13249             if (pae.intent == null && pae.receiver == null) {
13250                 // Caller is just waiting for the result.
13251                 return;
13252             }
13253         }
13254         // We are now ready to launch the assist activity.
13255         IResultReceiver sendReceiver = null;
13256         Bundle sendBundle = null;
13257         synchronized (this) {
13258             buildAssistBundleLocked(pae, extras);
13259             boolean exists = mPendingAssistExtras.remove(pae);
13260             mUiHandler.removeCallbacks(pae);
13261             if (!exists) {
13262                 // Timed out.
13263                 return;
13264             }
13265             if ((sendReceiver=pae.receiver) != null) {
13266                 // Caller wants result sent back to them.
13267                 sendBundle = new Bundle();
13268                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13269                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13270                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13271                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13272                         pae.receiverExtras);
13273             }
13274         }
13275         if (sendReceiver != null) {
13276             try {
13277                 sendReceiver.send(0, sendBundle);
13278             } catch (RemoteException e) {
13279             }
13280             return;
13281         }
13282
13283         final long ident = Binder.clearCallingIdentity();
13284         try {
13285             if (TextUtils.equals(pae.intent.getAction(),
13286                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13287                 pae.intent.putExtras(pae.extras);
13288                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13289             } else {
13290                 pae.intent.replaceExtras(pae.extras);
13291                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13292                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13293                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13294                 closeSystemDialogs("assist");
13295
13296                 try {
13297                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13298                 } catch (ActivityNotFoundException e) {
13299                     Slog.w(TAG, "No activity to handle assist action.", e);
13300                 }
13301             }
13302         } finally {
13303             Binder.restoreCallingIdentity(ident);
13304         }
13305     }
13306
13307     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13308             Bundle args) {
13309         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13310                 true /* focused */, true /* newSessionId */, userHandle, args,
13311                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13312     }
13313
13314     public void registerProcessObserver(IProcessObserver observer) {
13315         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13316                 "registerProcessObserver()");
13317         synchronized (this) {
13318             mProcessObservers.register(observer);
13319         }
13320     }
13321
13322     @Override
13323     public void unregisterProcessObserver(IProcessObserver observer) {
13324         synchronized (this) {
13325             mProcessObservers.unregister(observer);
13326         }
13327     }
13328
13329     @Override
13330     public int getUidProcessState(int uid, String callingPackage) {
13331         if (!hasUsageStatsPermission(callingPackage)) {
13332             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13333                     "getUidProcessState");
13334         }
13335
13336         synchronized (this) {
13337             UidRecord uidRec = mActiveUids.get(uid);
13338             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13339         }
13340     }
13341
13342     @Override
13343     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13344             String callingPackage) {
13345         if (!hasUsageStatsPermission(callingPackage)) {
13346             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13347                     "registerUidObserver");
13348         }
13349         synchronized (this) {
13350             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13351                     callingPackage, which, cutpoint));
13352         }
13353     }
13354
13355     @Override
13356     public void unregisterUidObserver(IUidObserver observer) {
13357         synchronized (this) {
13358             mUidObservers.unregister(observer);
13359         }
13360     }
13361
13362     @Override
13363     public boolean convertFromTranslucent(IBinder token) {
13364         final long origId = Binder.clearCallingIdentity();
13365         try {
13366             synchronized (this) {
13367                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13368                 if (r == null) {
13369                     return false;
13370                 }
13371                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13372                 if (translucentChanged) {
13373                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13374                 }
13375                 mWindowManager.setAppFullscreen(token, true);
13376                 return translucentChanged;
13377             }
13378         } finally {
13379             Binder.restoreCallingIdentity(origId);
13380         }
13381     }
13382
13383     @Override
13384     public boolean convertToTranslucent(IBinder token, Bundle options) {
13385         final long origId = Binder.clearCallingIdentity();
13386         try {
13387             synchronized (this) {
13388                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13389                 if (r == null) {
13390                     return false;
13391                 }
13392                 final TaskRecord task = r.getTask();
13393                 int index = task.mActivities.lastIndexOf(r);
13394                 if (index > 0) {
13395                     ActivityRecord under = task.mActivities.get(index - 1);
13396                     under.returningOptions = ActivityOptions.fromBundle(options);
13397                 }
13398                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13399                 if (translucentChanged) {
13400                     r.getStack().convertActivityToTranslucent(r);
13401                 }
13402                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13403                 mWindowManager.setAppFullscreen(token, false);
13404                 return translucentChanged;
13405             }
13406         } finally {
13407             Binder.restoreCallingIdentity(origId);
13408         }
13409     }
13410
13411     @Override
13412     public Bundle getActivityOptions(IBinder token) {
13413         final long origId = Binder.clearCallingIdentity();
13414         try {
13415             synchronized (this) {
13416                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13417                 if (r != null) {
13418                     final ActivityOptions activityOptions = r.takeOptionsLocked();
13419                     return activityOptions == null ? null : activityOptions.toBundle();
13420                 }
13421                 return null;
13422             }
13423         } finally {
13424             Binder.restoreCallingIdentity(origId);
13425         }
13426     }
13427
13428     @Override
13429     public void setImmersive(IBinder token, boolean immersive) {
13430         synchronized(this) {
13431             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13432             if (r == null) {
13433                 throw new IllegalArgumentException();
13434             }
13435             r.immersive = immersive;
13436
13437             // update associated state if we're frontmost
13438             if (r == mStackSupervisor.getResumedActivityLocked()) {
13439                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13440                 applyUpdateLockStateLocked(r);
13441             }
13442         }
13443     }
13444
13445     @Override
13446     public boolean isImmersive(IBinder token) {
13447         synchronized (this) {
13448             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13449             if (r == null) {
13450                 throw new IllegalArgumentException();
13451             }
13452             return r.immersive;
13453         }
13454     }
13455
13456     @Override
13457     public void setVrThread(int tid) {
13458         enforceSystemHasVrFeature();
13459         synchronized (this) {
13460             synchronized (mPidsSelfLocked) {
13461                 final int pid = Binder.getCallingPid();
13462                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13463                 mVrController.setVrThreadLocked(tid, pid, proc);
13464             }
13465         }
13466     }
13467
13468     @Override
13469     public void setPersistentVrThread(int tid) {
13470         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13471             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13472                     + Binder.getCallingPid()
13473                     + ", uid=" + Binder.getCallingUid()
13474                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13475             Slog.w(TAG, msg);
13476             throw new SecurityException(msg);
13477         }
13478         enforceSystemHasVrFeature();
13479         synchronized (this) {
13480             synchronized (mPidsSelfLocked) {
13481                 final int pid = Binder.getCallingPid();
13482                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13483                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13484             }
13485         }
13486     }
13487
13488     /**
13489      * Schedule the given thread a normal scheduling priority.
13490      *
13491      * @param tid the tid of the thread to adjust the scheduling of.
13492      * @param suppressLogs {@code true} if any error logging should be disabled.
13493      *
13494      * @return {@code true} if this succeeded.
13495      */
13496     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13497         try {
13498             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13499             return true;
13500         } catch (IllegalArgumentException e) {
13501             if (!suppressLogs) {
13502                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13503             }
13504         } catch (SecurityException e) {
13505             if (!suppressLogs) {
13506                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13507             }
13508         }
13509         return false;
13510     }
13511
13512     /**
13513      * Schedule the given thread an FIFO scheduling priority.
13514      *
13515      * @param tid the tid of the thread to adjust the scheduling of.
13516      * @param suppressLogs {@code true} if any error logging should be disabled.
13517      *
13518      * @return {@code true} if this succeeded.
13519      */
13520     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13521         try {
13522             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13523             return true;
13524         } catch (IllegalArgumentException e) {
13525             if (!suppressLogs) {
13526                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13527             }
13528         } catch (SecurityException e) {
13529             if (!suppressLogs) {
13530                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13531             }
13532         }
13533         return false;
13534     }
13535
13536     /**
13537      * Check that we have the features required for VR-related API calls, and throw an exception if
13538      * not.
13539      */
13540     private void enforceSystemHasVrFeature() {
13541         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13542             throw new UnsupportedOperationException("VR mode not supported on this device!");
13543         }
13544     }
13545
13546     @Override
13547     public void setRenderThread(int tid) {
13548         synchronized (this) {
13549             ProcessRecord proc;
13550             int pid = Binder.getCallingPid();
13551             if (pid == Process.myPid()) {
13552                 demoteSystemServerRenderThread(tid);
13553                 return;
13554             }
13555             synchronized (mPidsSelfLocked) {
13556                 proc = mPidsSelfLocked.get(pid);
13557                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13558                     // ensure the tid belongs to the process
13559                     if (!isThreadInProcess(pid, tid)) {
13560                         throw new IllegalArgumentException(
13561                             "Render thread does not belong to process");
13562                     }
13563                     proc.renderThreadTid = tid;
13564                     if (DEBUG_OOM_ADJ) {
13565                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13566                     }
13567                     // promote to FIFO now
13568                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13569                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13570                         if (mUseFifoUiScheduling) {
13571                             setThreadScheduler(proc.renderThreadTid,
13572                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13573                         } else {
13574                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13575                         }
13576                     }
13577                 } else {
13578                     if (DEBUG_OOM_ADJ) {
13579                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13580                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13581                                mUseFifoUiScheduling);
13582                     }
13583                 }
13584             }
13585         }
13586     }
13587
13588     /**
13589      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13590      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13591      *
13592      * @param tid the tid of the RenderThread
13593      */
13594     private void demoteSystemServerRenderThread(int tid) {
13595         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13596     }
13597
13598     @Override
13599     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13600         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13601             throw new UnsupportedOperationException("VR mode not supported on this device!");
13602         }
13603
13604         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13605
13606         ActivityRecord r;
13607         synchronized (this) {
13608             r = ActivityRecord.isInStackLocked(token);
13609         }
13610
13611         if (r == null) {
13612             throw new IllegalArgumentException();
13613         }
13614
13615         int err;
13616         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13617                 VrManagerInternal.NO_ERROR) {
13618             return err;
13619         }
13620
13621         synchronized(this) {
13622             r.requestedVrComponent = (enabled) ? packageName : null;
13623
13624             // Update associated state if this activity is currently focused
13625             if (r == mStackSupervisor.getResumedActivityLocked()) {
13626                 applyUpdateVrModeLocked(r);
13627             }
13628             return 0;
13629         }
13630     }
13631
13632     @Override
13633     public boolean isVrModePackageEnabled(ComponentName packageName) {
13634         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13635             throw new UnsupportedOperationException("VR mode not supported on this device!");
13636         }
13637
13638         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13639
13640         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13641                 VrManagerInternal.NO_ERROR;
13642     }
13643
13644     public boolean isTopActivityImmersive() {
13645         enforceNotIsolatedCaller("startActivity");
13646         synchronized (this) {
13647             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13648             return (r != null) ? r.immersive : false;
13649         }
13650     }
13651
13652     /**
13653      * @return whether the system should disable UI modes incompatible with VR mode.
13654      */
13655     boolean shouldDisableNonVrUiLocked() {
13656         return mVrController.shouldDisableNonVrUiLocked();
13657     }
13658
13659     @Override
13660     public boolean isTopOfTask(IBinder token) {
13661         synchronized (this) {
13662             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13663             if (r == null) {
13664                 throw new IllegalArgumentException();
13665             }
13666             return r.getTask().getTopActivity() == r;
13667         }
13668     }
13669
13670     @Override
13671     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13672         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13673             String msg = "Permission Denial: setHasTopUi() from pid="
13674                     + Binder.getCallingPid()
13675                     + ", uid=" + Binder.getCallingUid()
13676                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13677             Slog.w(TAG, msg);
13678             throw new SecurityException(msg);
13679         }
13680         final int pid = Binder.getCallingPid();
13681         final long origId = Binder.clearCallingIdentity();
13682         try {
13683             synchronized (this) {
13684                 boolean changed = false;
13685                 ProcessRecord pr;
13686                 synchronized (mPidsSelfLocked) {
13687                     pr = mPidsSelfLocked.get(pid);
13688                     if (pr == null) {
13689                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13690                         return;
13691                     }
13692                     if (pr.hasTopUi != hasTopUi) {
13693                         if (DEBUG_OOM_ADJ) {
13694                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13695                         }
13696                         pr.hasTopUi = hasTopUi;
13697                         changed = true;
13698                     }
13699                 }
13700                 if (changed) {
13701                     updateOomAdjLocked(pr, true);
13702                 }
13703             }
13704         } finally {
13705             Binder.restoreCallingIdentity(origId);
13706         }
13707     }
13708
13709     public final void enterSafeMode() {
13710         synchronized(this) {
13711             // It only makes sense to do this before the system is ready
13712             // and started launching other packages.
13713             if (!mSystemReady) {
13714                 try {
13715                     AppGlobals.getPackageManager().enterSafeMode();
13716                 } catch (RemoteException e) {
13717                 }
13718             }
13719
13720             mSafeMode = true;
13721         }
13722     }
13723
13724     public final void showSafeModeOverlay() {
13725         View v = LayoutInflater.from(mContext).inflate(
13726                 com.android.internal.R.layout.safe_mode, null);
13727         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13728         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13729         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13730         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13731         lp.gravity = Gravity.BOTTOM | Gravity.START;
13732         lp.format = v.getBackground().getOpacity();
13733         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13734                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13735         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13736         ((WindowManager)mContext.getSystemService(
13737                 Context.WINDOW_SERVICE)).addView(v, lp);
13738     }
13739
13740     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13741         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13742             return;
13743         }
13744         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13745         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13746         synchronized (stats) {
13747             if (mBatteryStatsService.isOnBattery()) {
13748                 mBatteryStatsService.enforceCallingPermission();
13749                 int MY_UID = Binder.getCallingUid();
13750                 final int uid;
13751                 if (sender == null) {
13752                     uid = sourceUid;
13753                 } else {
13754                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13755                 }
13756                 BatteryStatsImpl.Uid.Pkg pkg =
13757                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13758                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13759                 pkg.noteWakeupAlarmLocked(tag);
13760             }
13761         }
13762     }
13763
13764     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13765         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13766             return;
13767         }
13768         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13769         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13770         synchronized (stats) {
13771             mBatteryStatsService.enforceCallingPermission();
13772             int MY_UID = Binder.getCallingUid();
13773             final int uid;
13774             if (sender == null) {
13775                 uid = sourceUid;
13776             } else {
13777                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13778             }
13779             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13780         }
13781     }
13782
13783     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13784         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13785             return;
13786         }
13787         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13788         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13789         synchronized (stats) {
13790             mBatteryStatsService.enforceCallingPermission();
13791             int MY_UID = Binder.getCallingUid();
13792             final int uid;
13793             if (sender == null) {
13794                 uid = sourceUid;
13795             } else {
13796                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13797             }
13798             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13799         }
13800     }
13801
13802     public boolean killPids(int[] pids, String pReason, boolean secure) {
13803         if (Binder.getCallingUid() != SYSTEM_UID) {
13804             throw new SecurityException("killPids only available to the system");
13805         }
13806         String reason = (pReason == null) ? "Unknown" : pReason;
13807         // XXX Note: don't acquire main activity lock here, because the window
13808         // manager calls in with its locks held.
13809
13810         boolean killed = false;
13811         synchronized (mPidsSelfLocked) {
13812             int worstType = 0;
13813             for (int i=0; i<pids.length; i++) {
13814                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13815                 if (proc != null) {
13816                     int type = proc.setAdj;
13817                     if (type > worstType) {
13818                         worstType = type;
13819                     }
13820                 }
13821             }
13822
13823             // If the worst oom_adj is somewhere in the cached proc LRU range,
13824             // then constrain it so we will kill all cached procs.
13825             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13826                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13827                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13828             }
13829
13830             // If this is not a secure call, don't let it kill processes that
13831             // are important.
13832             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13833                 worstType = ProcessList.SERVICE_ADJ;
13834             }
13835
13836             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13837             for (int i=0; i<pids.length; i++) {
13838                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13839                 if (proc == null) {
13840                     continue;
13841                 }
13842                 int adj = proc.setAdj;
13843                 if (adj >= worstType && !proc.killedByAm) {
13844                     proc.kill(reason, true);
13845                     killed = true;
13846                 }
13847             }
13848         }
13849         return killed;
13850     }
13851
13852     @Override
13853     public void killUid(int appId, int userId, String reason) {
13854         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13855         synchronized (this) {
13856             final long identity = Binder.clearCallingIdentity();
13857             try {
13858                 killPackageProcessesLocked(null, appId, userId,
13859                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13860                         reason != null ? reason : "kill uid");
13861             } finally {
13862                 Binder.restoreCallingIdentity(identity);
13863             }
13864         }
13865     }
13866
13867     @Override
13868     public boolean killProcessesBelowForeground(String reason) {
13869         if (Binder.getCallingUid() != SYSTEM_UID) {
13870             throw new SecurityException("killProcessesBelowForeground() only available to system");
13871         }
13872
13873         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13874     }
13875
13876     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13877         if (Binder.getCallingUid() != SYSTEM_UID) {
13878             throw new SecurityException("killProcessesBelowAdj() only available to system");
13879         }
13880
13881         boolean killed = false;
13882         synchronized (mPidsSelfLocked) {
13883             final int size = mPidsSelfLocked.size();
13884             for (int i = 0; i < size; i++) {
13885                 final int pid = mPidsSelfLocked.keyAt(i);
13886                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13887                 if (proc == null) continue;
13888
13889                 final int adj = proc.setAdj;
13890                 if (adj > belowAdj && !proc.killedByAm) {
13891                     proc.kill(reason, true);
13892                     killed = true;
13893                 }
13894             }
13895         }
13896         return killed;
13897     }
13898
13899     @Override
13900     public void hang(final IBinder who, boolean allowRestart) {
13901         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13902                 != PackageManager.PERMISSION_GRANTED) {
13903             throw new SecurityException("Requires permission "
13904                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13905         }
13906
13907         final IBinder.DeathRecipient death = new DeathRecipient() {
13908             @Override
13909             public void binderDied() {
13910                 synchronized (this) {
13911                     notifyAll();
13912                 }
13913             }
13914         };
13915
13916         try {
13917             who.linkToDeath(death, 0);
13918         } catch (RemoteException e) {
13919             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13920             return;
13921         }
13922
13923         synchronized (this) {
13924             Watchdog.getInstance().setAllowRestart(allowRestart);
13925             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13926             synchronized (death) {
13927                 while (who.isBinderAlive()) {
13928                     try {
13929                         death.wait();
13930                     } catch (InterruptedException e) {
13931                     }
13932                 }
13933             }
13934             Watchdog.getInstance().setAllowRestart(true);
13935         }
13936     }
13937
13938     @Override
13939     public void restart() {
13940         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13941                 != PackageManager.PERMISSION_GRANTED) {
13942             throw new SecurityException("Requires permission "
13943                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13944         }
13945
13946         Log.i(TAG, "Sending shutdown broadcast...");
13947
13948         BroadcastReceiver br = new BroadcastReceiver() {
13949             @Override public void onReceive(Context context, Intent intent) {
13950                 // Now the broadcast is done, finish up the low-level shutdown.
13951                 Log.i(TAG, "Shutting down activity manager...");
13952                 shutdown(10000);
13953                 Log.i(TAG, "Shutdown complete, restarting!");
13954                 killProcess(myPid());
13955                 System.exit(10);
13956             }
13957         };
13958
13959         // First send the high-level shut down broadcast.
13960         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13961         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13962         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13963         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13964         mContext.sendOrderedBroadcastAsUser(intent,
13965                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13966         */
13967         br.onReceive(mContext, intent);
13968     }
13969
13970     private long getLowRamTimeSinceIdle(long now) {
13971         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13972     }
13973
13974     @Override
13975     public void performIdleMaintenance() {
13976         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13977                 != PackageManager.PERMISSION_GRANTED) {
13978             throw new SecurityException("Requires permission "
13979                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13980         }
13981
13982         synchronized (this) {
13983             final long now = SystemClock.uptimeMillis();
13984             final long timeSinceLastIdle = now - mLastIdleTime;
13985             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13986             mLastIdleTime = now;
13987             mLowRamTimeSinceLastIdle = 0;
13988             if (mLowRamStartTime != 0) {
13989                 mLowRamStartTime = now;
13990             }
13991
13992             StringBuilder sb = new StringBuilder(128);
13993             sb.append("Idle maintenance over ");
13994             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13995             sb.append(" low RAM for ");
13996             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13997             Slog.i(TAG, sb.toString());
13998
13999             // If at least 1/3 of our time since the last idle period has been spent
14000             // with RAM low, then we want to kill processes.
14001             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14002
14003             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14004                 ProcessRecord proc = mLruProcesses.get(i);
14005                 if (proc.notCachedSinceIdle) {
14006                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14007                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14008                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14009                         if (doKilling && proc.initialIdlePss != 0
14010                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14011                             sb = new StringBuilder(128);
14012                             sb.append("Kill");
14013                             sb.append(proc.processName);
14014                             sb.append(" in idle maint: pss=");
14015                             sb.append(proc.lastPss);
14016                             sb.append(", swapPss=");
14017                             sb.append(proc.lastSwapPss);
14018                             sb.append(", initialPss=");
14019                             sb.append(proc.initialIdlePss);
14020                             sb.append(", period=");
14021                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14022                             sb.append(", lowRamPeriod=");
14023                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14024                             Slog.wtfQuiet(TAG, sb.toString());
14025                             proc.kill("idle maint (pss " + proc.lastPss
14026                                     + " from " + proc.initialIdlePss + ")", true);
14027                         }
14028                     }
14029                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14030                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14031                     proc.notCachedSinceIdle = true;
14032                     proc.initialIdlePss = 0;
14033                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14034                             mTestPssMode, isSleepingLocked(), now);
14035                 }
14036             }
14037
14038             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14039             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14040         }
14041     }
14042
14043     @Override
14044     public void sendIdleJobTrigger() {
14045         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14046                 != PackageManager.PERMISSION_GRANTED) {
14047             throw new SecurityException("Requires permission "
14048                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14049         }
14050
14051         final long ident = Binder.clearCallingIdentity();
14052         try {
14053             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14054                     .setPackage("android")
14055                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14056             broadcastIntent(null, intent, null, null, 0, null, null, null,
14057                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14058         } finally {
14059             Binder.restoreCallingIdentity(ident);
14060         }
14061     }
14062
14063     private void retrieveSettings() {
14064         final ContentResolver resolver = mContext.getContentResolver();
14065         final boolean freeformWindowManagement =
14066                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14067                         || Settings.Global.getInt(
14068                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14069
14070         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14071         final boolean supportsPictureInPicture = supportsMultiWindow &&
14072                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14073         final boolean supportsSplitScreenMultiWindow =
14074                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14075         final boolean supportsMultiDisplay = mContext.getPackageManager()
14076                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14077         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14078         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14079         final boolean alwaysFinishActivities =
14080                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14081         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14082         final boolean forceResizable = Settings.Global.getInt(
14083                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14084         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14085                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14086         final boolean supportsLeanbackOnly =
14087                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14088
14089         // Transfer any global setting for forcing RTL layout, into a System Property
14090         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14091
14092         final Configuration configuration = new Configuration();
14093         Settings.System.getConfiguration(resolver, configuration);
14094         if (forceRtl) {
14095             // This will take care of setting the correct layout direction flags
14096             configuration.setLayoutDirection(configuration.locale);
14097         }
14098
14099         synchronized (this) {
14100             mDebugApp = mOrigDebugApp = debugApp;
14101             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14102             mAlwaysFinishActivities = alwaysFinishActivities;
14103             mSupportsLeanbackOnly = supportsLeanbackOnly;
14104             mForceResizableActivities = forceResizable;
14105             final boolean multiWindowFormEnabled = freeformWindowManagement
14106                     || supportsSplitScreenMultiWindow
14107                     || supportsPictureInPicture
14108                     || supportsMultiDisplay;
14109             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14110                 mSupportsMultiWindow = true;
14111                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14112                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14113                 mSupportsPictureInPicture = supportsPictureInPicture;
14114                 mSupportsMultiDisplay = supportsMultiDisplay;
14115             } else {
14116                 mSupportsMultiWindow = false;
14117                 mSupportsFreeformWindowManagement = false;
14118                 mSupportsSplitScreenMultiWindow = false;
14119                 mSupportsPictureInPicture = false;
14120                 mSupportsMultiDisplay = false;
14121             }
14122             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14123             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14124             // This happens before any activities are started, so we can change global configuration
14125             // in-place.
14126             updateConfigurationLocked(configuration, null, true);
14127             final Configuration globalConfig = getGlobalConfiguration();
14128             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14129
14130             // Load resources only after the current configuration has been set.
14131             final Resources res = mContext.getResources();
14132             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14133             mThumbnailWidth = res.getDimensionPixelSize(
14134                     com.android.internal.R.dimen.thumbnail_width);
14135             mThumbnailHeight = res.getDimensionPixelSize(
14136                     com.android.internal.R.dimen.thumbnail_height);
14137             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14138                     com.android.internal.R.string.config_appsNotReportingCrashes));
14139             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14140                     com.android.internal.R.bool.config_customUserSwitchUi);
14141             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14142                 mFullscreenThumbnailScale = (float) res
14143                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14144                     (float) globalConfig.screenWidthDp;
14145             } else {
14146                 mFullscreenThumbnailScale = res.getFraction(
14147                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14148             }
14149             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14150         }
14151     }
14152
14153     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14154         traceLog.traceBegin("PhaseActivityManagerReady");
14155         synchronized(this) {
14156             if (mSystemReady) {
14157                 // If we're done calling all the receivers, run the next "boot phase" passed in
14158                 // by the SystemServer
14159                 if (goingCallback != null) {
14160                     goingCallback.run();
14161                 }
14162                 return;
14163             }
14164
14165             mLocalDeviceIdleController
14166                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14167             mAssistUtils = new AssistUtils(mContext);
14168             mVrController.onSystemReady();
14169             // Make sure we have the current profile info, since it is needed for security checks.
14170             mUserController.onSystemReady();
14171             mRecentTasks.onSystemReadyLocked();
14172             mAppOpsService.systemReady();
14173             mSystemReady = true;
14174         }
14175
14176         try {
14177             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14178                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14179                     .getSerial();
14180         } catch (RemoteException e) {}
14181
14182         ArrayList<ProcessRecord> procsToKill = null;
14183         synchronized(mPidsSelfLocked) {
14184             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14185                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14186                 if (!isAllowedWhileBooting(proc.info)){
14187                     if (procsToKill == null) {
14188                         procsToKill = new ArrayList<ProcessRecord>();
14189                     }
14190                     procsToKill.add(proc);
14191                 }
14192             }
14193         }
14194
14195         synchronized(this) {
14196             if (procsToKill != null) {
14197                 for (int i=procsToKill.size()-1; i>=0; i--) {
14198                     ProcessRecord proc = procsToKill.get(i);
14199                     Slog.i(TAG, "Removing system update proc: " + proc);
14200                     removeProcessLocked(proc, true, false, "system update done");
14201                 }
14202             }
14203
14204             // Now that we have cleaned up any update processes, we
14205             // are ready to start launching real processes and know that
14206             // we won't trample on them any more.
14207             mProcessesReady = true;
14208         }
14209
14210         Slog.i(TAG, "System now ready");
14211         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14212             SystemClock.uptimeMillis());
14213
14214         synchronized(this) {
14215             // Make sure we have no pre-ready processes sitting around.
14216
14217             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14218                 ResolveInfo ri = mContext.getPackageManager()
14219                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14220                                 STOCK_PM_FLAGS);
14221                 CharSequence errorMsg = null;
14222                 if (ri != null) {
14223                     ActivityInfo ai = ri.activityInfo;
14224                     ApplicationInfo app = ai.applicationInfo;
14225                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14226                         mTopAction = Intent.ACTION_FACTORY_TEST;
14227                         mTopData = null;
14228                         mTopComponent = new ComponentName(app.packageName,
14229                                 ai.name);
14230                     } else {
14231                         errorMsg = mContext.getResources().getText(
14232                                 com.android.internal.R.string.factorytest_not_system);
14233                     }
14234                 } else {
14235                     errorMsg = mContext.getResources().getText(
14236                             com.android.internal.R.string.factorytest_no_action);
14237                 }
14238                 if (errorMsg != null) {
14239                     mTopAction = null;
14240                     mTopData = null;
14241                     mTopComponent = null;
14242                     Message msg = Message.obtain();
14243                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14244                     msg.getData().putCharSequence("msg", errorMsg);
14245                     mUiHandler.sendMessage(msg);
14246                 }
14247             }
14248         }
14249
14250         retrieveSettings();
14251         final int currentUserId;
14252         synchronized (this) {
14253             currentUserId = mUserController.getCurrentUserIdLocked();
14254             readGrantedUriPermissionsLocked();
14255         }
14256
14257         if (goingCallback != null) goingCallback.run();
14258         traceLog.traceBegin("ActivityManagerStartApps");
14259         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14260                 Integer.toString(currentUserId), currentUserId);
14261         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14262                 Integer.toString(currentUserId), currentUserId);
14263         mSystemServiceManager.startUser(currentUserId);
14264
14265         synchronized (this) {
14266             // Only start up encryption-aware persistent apps; once user is
14267             // unlocked we'll come back around and start unaware apps
14268             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14269
14270             // Start up initial activity.
14271             mBooting = true;
14272             // Enable home activity for system user, so that the system can always boot. We don't
14273             // do this when the system user is not setup since the setup wizard should be the one
14274             // to handle home activity in this case.
14275             if (UserManager.isSplitSystemUser() &&
14276                     Settings.Secure.getInt(mContext.getContentResolver(),
14277                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14278                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14279                 try {
14280                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14281                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14282                             UserHandle.USER_SYSTEM);
14283                 } catch (RemoteException e) {
14284                     throw e.rethrowAsRuntimeException();
14285                 }
14286             }
14287             startHomeActivityLocked(currentUserId, "systemReady");
14288
14289             try {
14290                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14291                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14292                             + " data partition or your device will be unstable.");
14293                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14294                 }
14295             } catch (RemoteException e) {
14296             }
14297
14298             if (!Build.isBuildConsistent()) {
14299                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14300                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14301             }
14302
14303             long ident = Binder.clearCallingIdentity();
14304             try {
14305                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14306                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14307                         | Intent.FLAG_RECEIVER_FOREGROUND);
14308                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14309                 broadcastIntentLocked(null, null, intent,
14310                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14311                         null, false, false, MY_PID, SYSTEM_UID,
14312                         currentUserId);
14313                 intent = new Intent(Intent.ACTION_USER_STARTING);
14314                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14315                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14316                 broadcastIntentLocked(null, null, intent,
14317                         null, new IIntentReceiver.Stub() {
14318                             @Override
14319                             public void performReceive(Intent intent, int resultCode, String data,
14320                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14321                                     throws RemoteException {
14322                             }
14323                         }, 0, null, null,
14324                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14325                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14326             } catch (Throwable t) {
14327                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14328             } finally {
14329                 Binder.restoreCallingIdentity(ident);
14330             }
14331             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14332             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14333             traceLog.traceEnd(); // ActivityManagerStartApps
14334             traceLog.traceEnd(); // PhaseActivityManagerReady
14335         }
14336     }
14337
14338     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14339         synchronized (this) {
14340             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14341         }
14342     }
14343
14344     void skipCurrentReceiverLocked(ProcessRecord app) {
14345         for (BroadcastQueue queue : mBroadcastQueues) {
14346             queue.skipCurrentReceiverLocked(app);
14347         }
14348     }
14349
14350     /**
14351      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14352      * The application process will exit immediately after this call returns.
14353      * @param app object of the crashing app, null for the system server
14354      * @param crashInfo describing the exception
14355      */
14356     public void handleApplicationCrash(IBinder app,
14357             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14358         ProcessRecord r = findAppProcess(app, "Crash");
14359         final String processName = app == null ? "system_server"
14360                 : (r == null ? "unknown" : r.processName);
14361
14362         handleApplicationCrashInner("crash", r, processName, crashInfo);
14363     }
14364
14365     /* Native crash reporting uses this inner version because it needs to be somewhat
14366      * decoupled from the AM-managed cleanup lifecycle
14367      */
14368     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14369             ApplicationErrorReport.CrashInfo crashInfo) {
14370         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14371                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14372                 r == null ? -1 : r.info.flags,
14373                 crashInfo.exceptionClassName,
14374                 crashInfo.exceptionMessage,
14375                 crashInfo.throwFileName,
14376                 crashInfo.throwLineNumber);
14377
14378         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14379
14380         mAppErrors.crashApplication(r, crashInfo);
14381     }
14382
14383     public void handleApplicationStrictModeViolation(
14384             IBinder app,
14385             int violationMask,
14386             StrictMode.ViolationInfo info) {
14387         ProcessRecord r = findAppProcess(app, "StrictMode");
14388         if (r == null) {
14389             return;
14390         }
14391
14392         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14393             Integer stackFingerprint = info.hashCode();
14394             boolean logIt = true;
14395             synchronized (mAlreadyLoggedViolatedStacks) {
14396                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14397                     logIt = false;
14398                     // TODO: sub-sample into EventLog for these, with
14399                     // the info.durationMillis?  Then we'd get
14400                     // the relative pain numbers, without logging all
14401                     // the stack traces repeatedly.  We'd want to do
14402                     // likewise in the client code, which also does
14403                     // dup suppression, before the Binder call.
14404                 } else {
14405                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14406                         mAlreadyLoggedViolatedStacks.clear();
14407                     }
14408                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14409                 }
14410             }
14411             if (logIt) {
14412                 logStrictModeViolationToDropBox(r, info);
14413             }
14414         }
14415
14416         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14417             AppErrorResult result = new AppErrorResult();
14418             synchronized (this) {
14419                 final long origId = Binder.clearCallingIdentity();
14420
14421                 Message msg = Message.obtain();
14422                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14423                 HashMap<String, Object> data = new HashMap<String, Object>();
14424                 data.put("result", result);
14425                 data.put("app", r);
14426                 data.put("violationMask", violationMask);
14427                 data.put("info", info);
14428                 msg.obj = data;
14429                 mUiHandler.sendMessage(msg);
14430
14431                 Binder.restoreCallingIdentity(origId);
14432             }
14433             int res = result.get();
14434             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14435         }
14436     }
14437
14438     // Depending on the policy in effect, there could be a bunch of
14439     // these in quick succession so we try to batch these together to
14440     // minimize disk writes, number of dropbox entries, and maximize
14441     // compression, by having more fewer, larger records.
14442     private void logStrictModeViolationToDropBox(
14443             ProcessRecord process,
14444             StrictMode.ViolationInfo info) {
14445         if (info == null) {
14446             return;
14447         }
14448         final boolean isSystemApp = process == null ||
14449                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14450                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14451         final String processName = process == null ? "unknown" : process.processName;
14452         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14453         final DropBoxManager dbox = (DropBoxManager)
14454                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14455
14456         // Exit early if the dropbox isn't configured to accept this report type.
14457         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14458
14459         boolean bufferWasEmpty;
14460         boolean needsFlush;
14461         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14462         synchronized (sb) {
14463             bufferWasEmpty = sb.length() == 0;
14464             appendDropBoxProcessHeaders(process, processName, sb);
14465             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14466             sb.append("System-App: ").append(isSystemApp).append("\n");
14467             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14468             if (info.violationNumThisLoop != 0) {
14469                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14470             }
14471             if (info.numAnimationsRunning != 0) {
14472                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14473             }
14474             if (info.broadcastIntentAction != null) {
14475                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14476             }
14477             if (info.durationMillis != -1) {
14478                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14479             }
14480             if (info.numInstances != -1) {
14481                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14482             }
14483             if (info.tags != null) {
14484                 for (String tag : info.tags) {
14485                     sb.append("Span-Tag: ").append(tag).append("\n");
14486                 }
14487             }
14488             sb.append("\n");
14489             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14490                 sb.append(info.crashInfo.stackTrace);
14491                 sb.append("\n");
14492             }
14493             if (info.message != null) {
14494                 sb.append(info.message);
14495                 sb.append("\n");
14496             }
14497
14498             // Only buffer up to ~64k.  Various logging bits truncate
14499             // things at 128k.
14500             needsFlush = (sb.length() > 64 * 1024);
14501         }
14502
14503         // Flush immediately if the buffer's grown too large, or this
14504         // is a non-system app.  Non-system apps are isolated with a
14505         // different tag & policy and not batched.
14506         //
14507         // Batching is useful during internal testing with
14508         // StrictMode settings turned up high.  Without batching,
14509         // thousands of separate files could be created on boot.
14510         if (!isSystemApp || needsFlush) {
14511             new Thread("Error dump: " + dropboxTag) {
14512                 @Override
14513                 public void run() {
14514                     String report;
14515                     synchronized (sb) {
14516                         report = sb.toString();
14517                         sb.delete(0, sb.length());
14518                         sb.trimToSize();
14519                     }
14520                     if (report.length() != 0) {
14521                         dbox.addText(dropboxTag, report);
14522                     }
14523                 }
14524             }.start();
14525             return;
14526         }
14527
14528         // System app batching:
14529         if (!bufferWasEmpty) {
14530             // An existing dropbox-writing thread is outstanding, so
14531             // we don't need to start it up.  The existing thread will
14532             // catch the buffer appends we just did.
14533             return;
14534         }
14535
14536         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14537         // (After this point, we shouldn't access AMS internal data structures.)
14538         new Thread("Error dump: " + dropboxTag) {
14539             @Override
14540             public void run() {
14541                 // 5 second sleep to let stacks arrive and be batched together
14542                 try {
14543                     Thread.sleep(5000);  // 5 seconds
14544                 } catch (InterruptedException e) {}
14545
14546                 String errorReport;
14547                 synchronized (mStrictModeBuffer) {
14548                     errorReport = mStrictModeBuffer.toString();
14549                     if (errorReport.length() == 0) {
14550                         return;
14551                     }
14552                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14553                     mStrictModeBuffer.trimToSize();
14554                 }
14555                 dbox.addText(dropboxTag, errorReport);
14556             }
14557         }.start();
14558     }
14559
14560     /**
14561      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14562      * @param app object of the crashing app, null for the system server
14563      * @param tag reported by the caller
14564      * @param system whether this wtf is coming from the system
14565      * @param crashInfo describing the context of the error
14566      * @return true if the process should exit immediately (WTF is fatal)
14567      */
14568     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14569             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14570         final int callingUid = Binder.getCallingUid();
14571         final int callingPid = Binder.getCallingPid();
14572
14573         if (system) {
14574             // If this is coming from the system, we could very well have low-level
14575             // system locks held, so we want to do this all asynchronously.  And we
14576             // never want this to become fatal, so there is that too.
14577             mHandler.post(new Runnable() {
14578                 @Override public void run() {
14579                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14580                 }
14581             });
14582             return false;
14583         }
14584
14585         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14586                 crashInfo);
14587
14588         final boolean isFatal = Build.IS_ENG || Settings.Global
14589                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14590         final boolean isSystem = (r == null) || r.persistent;
14591
14592         if (isFatal && !isSystem) {
14593             mAppErrors.crashApplication(r, crashInfo);
14594             return true;
14595         } else {
14596             return false;
14597         }
14598     }
14599
14600     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14601             final ApplicationErrorReport.CrashInfo crashInfo) {
14602         final ProcessRecord r = findAppProcess(app, "WTF");
14603         final String processName = app == null ? "system_server"
14604                 : (r == null ? "unknown" : r.processName);
14605
14606         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14607                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14608
14609         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14610
14611         return r;
14612     }
14613
14614     /**
14615      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14616      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14617      */
14618     private ProcessRecord findAppProcess(IBinder app, String reason) {
14619         if (app == null) {
14620             return null;
14621         }
14622
14623         synchronized (this) {
14624             final int NP = mProcessNames.getMap().size();
14625             for (int ip=0; ip<NP; ip++) {
14626                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14627                 final int NA = apps.size();
14628                 for (int ia=0; ia<NA; ia++) {
14629                     ProcessRecord p = apps.valueAt(ia);
14630                     if (p.thread != null && p.thread.asBinder() == app) {
14631                         return p;
14632                     }
14633                 }
14634             }
14635
14636             Slog.w(TAG, "Can't find mystery application for " + reason
14637                     + " from pid=" + Binder.getCallingPid()
14638                     + " uid=" + Binder.getCallingUid() + ": " + app);
14639             return null;
14640         }
14641     }
14642
14643     /**
14644      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14645      * to append various headers to the dropbox log text.
14646      */
14647     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14648             StringBuilder sb) {
14649         // Watchdog thread ends up invoking this function (with
14650         // a null ProcessRecord) to add the stack file to dropbox.
14651         // Do not acquire a lock on this (am) in such cases, as it
14652         // could cause a potential deadlock, if and when watchdog
14653         // is invoked due to unavailability of lock on am and it
14654         // would prevent watchdog from killing system_server.
14655         if (process == null) {
14656             sb.append("Process: ").append(processName).append("\n");
14657             return;
14658         }
14659         // Note: ProcessRecord 'process' is guarded by the service
14660         // instance.  (notably process.pkgList, which could otherwise change
14661         // concurrently during execution of this method)
14662         synchronized (this) {
14663             sb.append("Process: ").append(processName).append("\n");
14664             sb.append("PID: ").append(process.pid).append("\n");
14665             int flags = process.info.flags;
14666             IPackageManager pm = AppGlobals.getPackageManager();
14667             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14668             for (int ip=0; ip<process.pkgList.size(); ip++) {
14669                 String pkg = process.pkgList.keyAt(ip);
14670                 sb.append("Package: ").append(pkg);
14671                 try {
14672                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14673                     if (pi != null) {
14674                         sb.append(" v").append(pi.versionCode);
14675                         if (pi.versionName != null) {
14676                             sb.append(" (").append(pi.versionName).append(")");
14677                         }
14678                     }
14679                 } catch (RemoteException e) {
14680                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14681                 }
14682                 sb.append("\n");
14683             }
14684             if (process.info.isInstantApp()) {
14685                 sb.append("Instant-App: true\n");
14686             }
14687         }
14688     }
14689
14690     private static String processClass(ProcessRecord process) {
14691         if (process == null || process.pid == MY_PID) {
14692             return "system_server";
14693         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14694             return "system_app";
14695         } else {
14696             return "data_app";
14697         }
14698     }
14699
14700     private volatile long mWtfClusterStart;
14701     private volatile int mWtfClusterCount;
14702
14703     /**
14704      * Write a description of an error (crash, WTF, ANR) to the drop box.
14705      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14706      * @param process which caused the error, null means the system server
14707      * @param activity which triggered the error, null if unknown
14708      * @param parent activity related to the error, null if unknown
14709      * @param subject line related to the error, null if absent
14710      * @param report in long form describing the error, null if absent
14711      * @param dataFile text file to include in the report, null if none
14712      * @param crashInfo giving an application stack trace, null if absent
14713      */
14714     public void addErrorToDropBox(String eventType,
14715             ProcessRecord process, String processName, ActivityRecord activity,
14716             ActivityRecord parent, String subject,
14717             final String report, final File dataFile,
14718             final ApplicationErrorReport.CrashInfo crashInfo) {
14719         // NOTE -- this must never acquire the ActivityManagerService lock,
14720         // otherwise the watchdog may be prevented from resetting the system.
14721
14722         // Bail early if not published yet
14723         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14724         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14725
14726         // Exit early if the dropbox isn't configured to accept this report type.
14727         final String dropboxTag = processClass(process) + "_" + eventType;
14728         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14729
14730         // Rate-limit how often we're willing to do the heavy lifting below to
14731         // collect and record logs; currently 5 logs per 10 second period.
14732         final long now = SystemClock.elapsedRealtime();
14733         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14734             mWtfClusterStart = now;
14735             mWtfClusterCount = 1;
14736         } else {
14737             if (mWtfClusterCount++ >= 5) return;
14738         }
14739
14740         final StringBuilder sb = new StringBuilder(1024);
14741         appendDropBoxProcessHeaders(process, processName, sb);
14742         if (process != null) {
14743             sb.append("Foreground: ")
14744                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14745                     .append("\n");
14746         }
14747         if (activity != null) {
14748             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14749         }
14750         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14751             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14752         }
14753         if (parent != null && parent != activity) {
14754             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14755         }
14756         if (subject != null) {
14757             sb.append("Subject: ").append(subject).append("\n");
14758         }
14759         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14760         if (Debug.isDebuggerConnected()) {
14761             sb.append("Debugger: Connected\n");
14762         }
14763         sb.append("\n");
14764
14765         // Do the rest in a worker thread to avoid blocking the caller on I/O
14766         // (After this point, we shouldn't access AMS internal data structures.)
14767         Thread worker = new Thread("Error dump: " + dropboxTag) {
14768             @Override
14769             public void run() {
14770                 if (report != null) {
14771                     sb.append(report);
14772                 }
14773
14774                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14775                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14776                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14777                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14778
14779                 if (dataFile != null && maxDataFileSize > 0) {
14780                     try {
14781                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14782                                     "\n\n[[TRUNCATED]]"));
14783                     } catch (IOException e) {
14784                         Slog.e(TAG, "Error reading " + dataFile, e);
14785                     }
14786                 }
14787                 if (crashInfo != null && crashInfo.stackTrace != null) {
14788                     sb.append(crashInfo.stackTrace);
14789                 }
14790
14791                 if (lines > 0) {
14792                     sb.append("\n");
14793
14794                     // Merge several logcat streams, and take the last N lines
14795                     InputStreamReader input = null;
14796                     try {
14797                         java.lang.Process logcat = new ProcessBuilder(
14798                                 "/system/bin/timeout", "-k", "15s", "10s",
14799                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14800                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14801                                         .redirectErrorStream(true).start();
14802
14803                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14804                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14805                         input = new InputStreamReader(logcat.getInputStream());
14806
14807                         int num;
14808                         char[] buf = new char[8192];
14809                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14810                     } catch (IOException e) {
14811                         Slog.e(TAG, "Error running logcat", e);
14812                     } finally {
14813                         if (input != null) try { input.close(); } catch (IOException e) {}
14814                     }
14815                 }
14816
14817                 dbox.addText(dropboxTag, sb.toString());
14818             }
14819         };
14820
14821         if (process == null) {
14822             // If process is null, we are being called from some internal code
14823             // and may be about to die -- run this synchronously.
14824             worker.run();
14825         } else {
14826             worker.start();
14827         }
14828     }
14829
14830     @Override
14831     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14832         enforceNotIsolatedCaller("getProcessesInErrorState");
14833         // assume our apps are happy - lazy create the list
14834         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14835
14836         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14837                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14838         int userId = UserHandle.getUserId(Binder.getCallingUid());
14839
14840         synchronized (this) {
14841
14842             // iterate across all processes
14843             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14844                 ProcessRecord app = mLruProcesses.get(i);
14845                 if (!allUsers && app.userId != userId) {
14846                     continue;
14847                 }
14848                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14849                     // This one's in trouble, so we'll generate a report for it
14850                     // crashes are higher priority (in case there's a crash *and* an anr)
14851                     ActivityManager.ProcessErrorStateInfo report = null;
14852                     if (app.crashing) {
14853                         report = app.crashingReport;
14854                     } else if (app.notResponding) {
14855                         report = app.notRespondingReport;
14856                     }
14857
14858                     if (report != null) {
14859                         if (errList == null) {
14860                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14861                         }
14862                         errList.add(report);
14863                     } else {
14864                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14865                                 " crashing = " + app.crashing +
14866                                 " notResponding = " + app.notResponding);
14867                     }
14868                 }
14869             }
14870         }
14871
14872         return errList;
14873     }
14874
14875     static int procStateToImportance(int procState, int memAdj,
14876             ActivityManager.RunningAppProcessInfo currApp,
14877             int clientTargetSdk) {
14878         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14879                 procState, clientTargetSdk);
14880         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14881             currApp.lru = memAdj;
14882         } else {
14883             currApp.lru = 0;
14884         }
14885         return imp;
14886     }
14887
14888     private void fillInProcMemInfo(ProcessRecord app,
14889             ActivityManager.RunningAppProcessInfo outInfo,
14890             int clientTargetSdk) {
14891         outInfo.pid = app.pid;
14892         outInfo.uid = app.info.uid;
14893         if (mHeavyWeightProcess == app) {
14894             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14895         }
14896         if (app.persistent) {
14897             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14898         }
14899         if (app.activities.size() > 0) {
14900             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14901         }
14902         outInfo.lastTrimLevel = app.trimMemoryLevel;
14903         int adj = app.curAdj;
14904         int procState = app.curProcState;
14905         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14906         outInfo.importanceReasonCode = app.adjTypeCode;
14907         outInfo.processState = app.curProcState;
14908     }
14909
14910     @Override
14911     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14912         enforceNotIsolatedCaller("getRunningAppProcesses");
14913
14914         final int callingUid = Binder.getCallingUid();
14915         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14916
14917         // Lazy instantiation of list
14918         List<ActivityManager.RunningAppProcessInfo> runList = null;
14919         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14920                 callingUid) == PackageManager.PERMISSION_GRANTED;
14921         final int userId = UserHandle.getUserId(callingUid);
14922         final boolean allUids = isGetTasksAllowed(
14923                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14924
14925         synchronized (this) {
14926             // Iterate across all processes
14927             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14928                 ProcessRecord app = mLruProcesses.get(i);
14929                 if ((!allUsers && app.userId != userId)
14930                         || (!allUids && app.uid != callingUid)) {
14931                     continue;
14932                 }
14933                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14934                     // Generate process state info for running application
14935                     ActivityManager.RunningAppProcessInfo currApp =
14936                         new ActivityManager.RunningAppProcessInfo(app.processName,
14937                                 app.pid, app.getPackageList());
14938                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14939                     if (app.adjSource instanceof ProcessRecord) {
14940                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14941                         currApp.importanceReasonImportance =
14942                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14943                                         app.adjSourceProcState);
14944                     } else if (app.adjSource instanceof ActivityRecord) {
14945                         ActivityRecord r = (ActivityRecord)app.adjSource;
14946                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14947                     }
14948                     if (app.adjTarget instanceof ComponentName) {
14949                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14950                     }
14951                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14952                     //        + " lru=" + currApp.lru);
14953                     if (runList == null) {
14954                         runList = new ArrayList<>();
14955                     }
14956                     runList.add(currApp);
14957                 }
14958             }
14959         }
14960         return runList;
14961     }
14962
14963     @Override
14964     public List<ApplicationInfo> getRunningExternalApplications() {
14965         enforceNotIsolatedCaller("getRunningExternalApplications");
14966         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14967         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14968         if (runningApps != null && runningApps.size() > 0) {
14969             Set<String> extList = new HashSet<String>();
14970             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14971                 if (app.pkgList != null) {
14972                     for (String pkg : app.pkgList) {
14973                         extList.add(pkg);
14974                     }
14975                 }
14976             }
14977             IPackageManager pm = AppGlobals.getPackageManager();
14978             for (String pkg : extList) {
14979                 try {
14980                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14981                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14982                         retList.add(info);
14983                     }
14984                 } catch (RemoteException e) {
14985                 }
14986             }
14987         }
14988         return retList;
14989     }
14990
14991     @Override
14992     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14993         enforceNotIsolatedCaller("getMyMemoryState");
14994
14995         final int callingUid = Binder.getCallingUid();
14996         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14997
14998         synchronized (this) {
14999             ProcessRecord proc;
15000             synchronized (mPidsSelfLocked) {
15001                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15002             }
15003             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15004         }
15005     }
15006
15007     @Override
15008     public int getMemoryTrimLevel() {
15009         enforceNotIsolatedCaller("getMyMemoryState");
15010         synchronized (this) {
15011             return mLastMemoryLevel;
15012         }
15013     }
15014
15015     @Override
15016     public void onShellCommand(FileDescriptor in, FileDescriptor out,
15017             FileDescriptor err, String[] args, ShellCallback callback,
15018             ResultReceiver resultReceiver) {
15019         (new ActivityManagerShellCommand(this, false)).exec(
15020                 this, in, out, err, args, callback, resultReceiver);
15021     }
15022
15023     SleepToken acquireSleepToken(String tag, int displayId) {
15024         synchronized (this) {
15025             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15026             updateSleepIfNeededLocked();
15027             return token;
15028         }
15029     }
15030
15031     @Override
15032     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15033         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15034
15035         boolean dumpAll = false;
15036         boolean dumpClient = false;
15037         boolean dumpCheckin = false;
15038         boolean dumpCheckinFormat = false;
15039         boolean dumpVisibleStacksOnly = false;
15040         boolean dumpFocusedStackOnly = false;
15041         String dumpPackage = null;
15042
15043         int opti = 0;
15044         while (opti < args.length) {
15045             String opt = args[opti];
15046             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15047                 break;
15048             }
15049             opti++;
15050             if ("-a".equals(opt)) {
15051                 dumpAll = true;
15052             } else if ("-c".equals(opt)) {
15053                 dumpClient = true;
15054             } else if ("-v".equals(opt)) {
15055                 dumpVisibleStacksOnly = true;
15056             } else if ("-f".equals(opt)) {
15057                 dumpFocusedStackOnly = true;
15058             } else if ("-p".equals(opt)) {
15059                 if (opti < args.length) {
15060                     dumpPackage = args[opti];
15061                     opti++;
15062                 } else {
15063                     pw.println("Error: -p option requires package argument");
15064                     return;
15065                 }
15066                 dumpClient = true;
15067             } else if ("--checkin".equals(opt)) {
15068                 dumpCheckin = dumpCheckinFormat = true;
15069             } else if ("-C".equals(opt)) {
15070                 dumpCheckinFormat = true;
15071             } else if ("-h".equals(opt)) {
15072                 ActivityManagerShellCommand.dumpHelp(pw, true);
15073                 return;
15074             } else {
15075                 pw.println("Unknown argument: " + opt + "; use -h for help");
15076             }
15077         }
15078
15079         long origId = Binder.clearCallingIdentity();
15080         boolean more = false;
15081         // Is the caller requesting to dump a particular piece of data?
15082         if (opti < args.length) {
15083             String cmd = args[opti];
15084             opti++;
15085             if ("activities".equals(cmd) || "a".equals(cmd)) {
15086                 synchronized (this) {
15087                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15088                 }
15089             } else if ("lastanr".equals(cmd)) {
15090                 synchronized (this) {
15091                     dumpLastANRLocked(pw);
15092                 }
15093             } else if ("starter".equals(cmd)) {
15094                 synchronized (this) {
15095                     dumpActivityStarterLocked(pw, dumpPackage);
15096                 }
15097             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15098                 synchronized (this) {
15099                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15100                 }
15101             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15102                 String[] newArgs;
15103                 String name;
15104                 if (opti >= args.length) {
15105                     name = null;
15106                     newArgs = EMPTY_STRING_ARRAY;
15107                 } else {
15108                     dumpPackage = args[opti];
15109                     opti++;
15110                     newArgs = new String[args.length - opti];
15111                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15112                             args.length - opti);
15113                 }
15114                 synchronized (this) {
15115                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15116                 }
15117             } else if ("broadcast-stats".equals(cmd)) {
15118                 String[] newArgs;
15119                 String name;
15120                 if (opti >= args.length) {
15121                     name = null;
15122                     newArgs = EMPTY_STRING_ARRAY;
15123                 } else {
15124                     dumpPackage = args[opti];
15125                     opti++;
15126                     newArgs = new String[args.length - opti];
15127                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15128                             args.length - opti);
15129                 }
15130                 synchronized (this) {
15131                     if (dumpCheckinFormat) {
15132                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15133                                 dumpPackage);
15134                     } else {
15135                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15136                     }
15137                 }
15138             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15139                 String[] newArgs;
15140                 String name;
15141                 if (opti >= args.length) {
15142                     name = null;
15143                     newArgs = EMPTY_STRING_ARRAY;
15144                 } else {
15145                     dumpPackage = args[opti];
15146                     opti++;
15147                     newArgs = new String[args.length - opti];
15148                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15149                             args.length - opti);
15150                 }
15151                 synchronized (this) {
15152                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15153                 }
15154             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15155                 String[] newArgs;
15156                 String name;
15157                 if (opti >= args.length) {
15158                     name = null;
15159                     newArgs = EMPTY_STRING_ARRAY;
15160                 } else {
15161                     dumpPackage = args[opti];
15162                     opti++;
15163                     newArgs = new String[args.length - opti];
15164                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15165                             args.length - opti);
15166                 }
15167                 synchronized (this) {
15168                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15169                 }
15170             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15171                 synchronized (this) {
15172                     dumpOomLocked(fd, pw, args, opti, true);
15173                 }
15174             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15175                 synchronized (this) {
15176                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15177                 }
15178             } else if ("provider".equals(cmd)) {
15179                 String[] newArgs;
15180                 String name;
15181                 if (opti >= args.length) {
15182                     name = null;
15183                     newArgs = EMPTY_STRING_ARRAY;
15184                 } else {
15185                     name = args[opti];
15186                     opti++;
15187                     newArgs = new String[args.length - opti];
15188                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15189                 }
15190                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15191                     pw.println("No providers match: " + name);
15192                     pw.println("Use -h for help.");
15193                 }
15194             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15195                 synchronized (this) {
15196                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15197                 }
15198             } else if ("service".equals(cmd)) {
15199                 String[] newArgs;
15200                 String name;
15201                 if (opti >= args.length) {
15202                     name = null;
15203                     newArgs = EMPTY_STRING_ARRAY;
15204                 } else {
15205                     name = args[opti];
15206                     opti++;
15207                     newArgs = new String[args.length - opti];
15208                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15209                             args.length - opti);
15210                 }
15211                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15212                     pw.println("No services match: " + name);
15213                     pw.println("Use -h for help.");
15214                 }
15215             } else if ("package".equals(cmd)) {
15216                 String[] newArgs;
15217                 if (opti >= args.length) {
15218                     pw.println("package: no package name specified");
15219                     pw.println("Use -h for help.");
15220                 } else {
15221                     dumpPackage = args[opti];
15222                     opti++;
15223                     newArgs = new String[args.length - opti];
15224                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15225                             args.length - opti);
15226                     args = newArgs;
15227                     opti = 0;
15228                     more = true;
15229                 }
15230             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15231                 synchronized (this) {
15232                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15233                 }
15234             } else if ("settings".equals(cmd)) {
15235                 synchronized (this) {
15236                     mConstants.dump(pw);
15237                 }
15238             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15239                 if (dumpClient) {
15240                     ActiveServices.ServiceDumper dumper;
15241                     synchronized (this) {
15242                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15243                                 dumpPackage);
15244                     }
15245                     dumper.dumpWithClient();
15246                 } else {
15247                     synchronized (this) {
15248                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15249                                 dumpPackage).dumpLocked();
15250                     }
15251                 }
15252             } else if ("locks".equals(cmd)) {
15253                 LockGuard.dump(fd, pw, args);
15254             } else {
15255                 // Dumping a single activity?
15256                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15257                         dumpFocusedStackOnly)) {
15258                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15259                     int res = shell.exec(this, null, fd, null, args, null,
15260                             new ResultReceiver(null));
15261                     if (res < 0) {
15262                         pw.println("Bad activity command, or no activities match: " + cmd);
15263                         pw.println("Use -h for help.");
15264                     }
15265                 }
15266             }
15267             if (!more) {
15268                 Binder.restoreCallingIdentity(origId);
15269                 return;
15270             }
15271         }
15272
15273         // No piece of data specified, dump everything.
15274         if (dumpCheckinFormat) {
15275             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15276         } else if (dumpClient) {
15277             ActiveServices.ServiceDumper sdumper;
15278             synchronized (this) {
15279                 mConstants.dump(pw);
15280                 pw.println();
15281                 if (dumpAll) {
15282                     pw.println("-------------------------------------------------------------------------------");
15283                 }
15284                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15285                 pw.println();
15286                 if (dumpAll) {
15287                     pw.println("-------------------------------------------------------------------------------");
15288                 }
15289                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15290                 pw.println();
15291                 if (dumpAll) {
15292                     pw.println("-------------------------------------------------------------------------------");
15293                 }
15294                 if (dumpAll || dumpPackage != null) {
15295                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15296                     pw.println();
15297                     if (dumpAll) {
15298                         pw.println("-------------------------------------------------------------------------------");
15299                     }
15300                 }
15301                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15302                 pw.println();
15303                 if (dumpAll) {
15304                     pw.println("-------------------------------------------------------------------------------");
15305                 }
15306                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15307                 pw.println();
15308                 if (dumpAll) {
15309                     pw.println("-------------------------------------------------------------------------------");
15310                 }
15311                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15312                         dumpPackage);
15313             }
15314             sdumper.dumpWithClient();
15315             pw.println();
15316             synchronized (this) {
15317                 if (dumpAll) {
15318                     pw.println("-------------------------------------------------------------------------------");
15319                 }
15320                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15321                 pw.println();
15322                 if (dumpAll) {
15323                     pw.println("-------------------------------------------------------------------------------");
15324                 }
15325                 dumpLastANRLocked(pw);
15326                 pw.println();
15327                 if (dumpAll) {
15328                     pw.println("-------------------------------------------------------------------------------");
15329                 }
15330                 dumpActivityStarterLocked(pw, dumpPackage);
15331                 pw.println();
15332                 if (dumpAll) {
15333                     pw.println("-------------------------------------------------------------------------------");
15334                 }
15335                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15336                 if (mAssociations.size() > 0) {
15337                     pw.println();
15338                     if (dumpAll) {
15339                         pw.println("-------------------------------------------------------------------------------");
15340                     }
15341                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15342                 }
15343                 pw.println();
15344                 if (dumpAll) {
15345                     pw.println("-------------------------------------------------------------------------------");
15346                 }
15347                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15348             }
15349
15350         } else {
15351             synchronized (this) {
15352                 mConstants.dump(pw);
15353                 pw.println();
15354                 if (dumpAll) {
15355                     pw.println("-------------------------------------------------------------------------------");
15356                 }
15357                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15358                 pw.println();
15359                 if (dumpAll) {
15360                     pw.println("-------------------------------------------------------------------------------");
15361                 }
15362                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15363                 pw.println();
15364                 if (dumpAll) {
15365                     pw.println("-------------------------------------------------------------------------------");
15366                 }
15367                 if (dumpAll || dumpPackage != null) {
15368                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15369                     pw.println();
15370                     if (dumpAll) {
15371                         pw.println("-------------------------------------------------------------------------------");
15372                     }
15373                 }
15374                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15375                 pw.println();
15376                 if (dumpAll) {
15377                     pw.println("-------------------------------------------------------------------------------");
15378                 }
15379                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15380                 pw.println();
15381                 if (dumpAll) {
15382                     pw.println("-------------------------------------------------------------------------------");
15383                 }
15384                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15385                         .dumpLocked();
15386                 pw.println();
15387                 if (dumpAll) {
15388                     pw.println("-------------------------------------------------------------------------------");
15389                 }
15390                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15391                 pw.println();
15392                 if (dumpAll) {
15393                     pw.println("-------------------------------------------------------------------------------");
15394                 }
15395                 dumpLastANRLocked(pw);
15396                 pw.println();
15397                 if (dumpAll) {
15398                     pw.println("-------------------------------------------------------------------------------");
15399                 }
15400                 dumpActivityStarterLocked(pw, dumpPackage);
15401                 pw.println();
15402                 if (dumpAll) {
15403                     pw.println("-------------------------------------------------------------------------------");
15404                 }
15405                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15406                 if (mAssociations.size() > 0) {
15407                     pw.println();
15408                     if (dumpAll) {
15409                         pw.println("-------------------------------------------------------------------------------");
15410                     }
15411                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15412                 }
15413                 pw.println();
15414                 if (dumpAll) {
15415                     pw.println("-------------------------------------------------------------------------------");
15416                 }
15417                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15418             }
15419         }
15420         Binder.restoreCallingIdentity(origId);
15421     }
15422
15423     private void dumpLastANRLocked(PrintWriter pw) {
15424         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15425         if (mLastANRState == null) {
15426             pw.println("  <no ANR has occurred since boot>");
15427         } else {
15428             pw.println(mLastANRState);
15429         }
15430     }
15431
15432     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15433         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15434         mActivityStarter.dump(pw, "", dumpPackage);
15435     }
15436
15437     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15438             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15439         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15440                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15441     }
15442
15443     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15444             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15445         pw.println(header);
15446
15447         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15448                 dumpPackage);
15449         boolean needSep = printedAnything;
15450
15451         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15452                 mStackSupervisor.getResumedActivityLocked(),
15453                 dumpPackage, needSep, "  ResumedActivity: ");
15454         if (printed) {
15455             printedAnything = true;
15456             needSep = false;
15457         }
15458
15459         if (dumpPackage == null) {
15460             if (needSep) {
15461                 pw.println();
15462             }
15463             printedAnything = true;
15464             mStackSupervisor.dump(pw, "  ");
15465         }
15466
15467         if (!printedAnything) {
15468             pw.println("  (nothing)");
15469         }
15470     }
15471
15472     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15473             int opti, boolean dumpAll, String dumpPackage) {
15474         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15475
15476         boolean printedAnything = false;
15477
15478         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15479             boolean printedHeader = false;
15480
15481             final int N = mRecentTasks.size();
15482             for (int i=0; i<N; i++) {
15483                 TaskRecord tr = mRecentTasks.get(i);
15484                 if (dumpPackage != null) {
15485                     if (tr.realActivity == null ||
15486                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15487                         continue;
15488                     }
15489                 }
15490                 if (!printedHeader) {
15491                     pw.println("  Recent tasks:");
15492                     printedHeader = true;
15493                     printedAnything = true;
15494                 }
15495                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15496                         pw.println(tr);
15497                 if (dumpAll) {
15498                     mRecentTasks.get(i).dump(pw, "    ");
15499                 }
15500             }
15501         }
15502
15503         if (!printedAnything) {
15504             pw.println("  (nothing)");
15505         }
15506     }
15507
15508     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15509             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15510         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15511
15512         int dumpUid = 0;
15513         if (dumpPackage != null) {
15514             IPackageManager pm = AppGlobals.getPackageManager();
15515             try {
15516                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15517             } catch (RemoteException e) {
15518             }
15519         }
15520
15521         boolean printedAnything = false;
15522
15523         final long now = SystemClock.uptimeMillis();
15524
15525         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15526             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15527                     = mAssociations.valueAt(i1);
15528             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15529                 SparseArray<ArrayMap<String, Association>> sourceUids
15530                         = targetComponents.valueAt(i2);
15531                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15532                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15533                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15534                         Association ass = sourceProcesses.valueAt(i4);
15535                         if (dumpPackage != null) {
15536                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15537                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15538                                 continue;
15539                             }
15540                         }
15541                         printedAnything = true;
15542                         pw.print("  ");
15543                         pw.print(ass.mTargetProcess);
15544                         pw.print("/");
15545                         UserHandle.formatUid(pw, ass.mTargetUid);
15546                         pw.print(" <- ");
15547                         pw.print(ass.mSourceProcess);
15548                         pw.print("/");
15549                         UserHandle.formatUid(pw, ass.mSourceUid);
15550                         pw.println();
15551                         pw.print("    via ");
15552                         pw.print(ass.mTargetComponent.flattenToShortString());
15553                         pw.println();
15554                         pw.print("    ");
15555                         long dur = ass.mTime;
15556                         if (ass.mNesting > 0) {
15557                             dur += now - ass.mStartTime;
15558                         }
15559                         TimeUtils.formatDuration(dur, pw);
15560                         pw.print(" (");
15561                         pw.print(ass.mCount);
15562                         pw.print(" times)");
15563                         pw.print("  ");
15564                         for (int i=0; i<ass.mStateTimes.length; i++) {
15565                             long amt = ass.mStateTimes[i];
15566                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15567                                 amt += now - ass.mLastStateUptime;
15568                             }
15569                             if (amt != 0) {
15570                                 pw.print(" ");
15571                                 pw.print(ProcessList.makeProcStateString(
15572                                             i + ActivityManager.MIN_PROCESS_STATE));
15573                                 pw.print("=");
15574                                 TimeUtils.formatDuration(amt, pw);
15575                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15576                                     pw.print("*");
15577                                 }
15578                             }
15579                         }
15580                         pw.println();
15581                         if (ass.mNesting > 0) {
15582                             pw.print("    Currently active: ");
15583                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15584                             pw.println();
15585                         }
15586                     }
15587                 }
15588             }
15589
15590         }
15591
15592         if (!printedAnything) {
15593             pw.println("  (nothing)");
15594         }
15595     }
15596
15597     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15598             String header, boolean needSep) {
15599         boolean printed = false;
15600         int whichAppId = -1;
15601         if (dumpPackage != null) {
15602             try {
15603                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15604                         dumpPackage, 0);
15605                 whichAppId = UserHandle.getAppId(info.uid);
15606             } catch (NameNotFoundException e) {
15607                 e.printStackTrace();
15608             }
15609         }
15610         for (int i=0; i<uids.size(); i++) {
15611             UidRecord uidRec = uids.valueAt(i);
15612             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15613                 continue;
15614             }
15615             if (!printed) {
15616                 printed = true;
15617                 if (needSep) {
15618                     pw.println();
15619                 }
15620                 pw.print("  ");
15621                 pw.println(header);
15622                 needSep = true;
15623             }
15624             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15625             pw.print(": "); pw.println(uidRec);
15626         }
15627         return printed;
15628     }
15629
15630     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15631             int opti, boolean dumpAll, String dumpPackage) {
15632         boolean needSep = false;
15633         boolean printedAnything = false;
15634         int numPers = 0;
15635
15636         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15637
15638         if (dumpAll) {
15639             final int NP = mProcessNames.getMap().size();
15640             for (int ip=0; ip<NP; ip++) {
15641                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15642                 final int NA = procs.size();
15643                 for (int ia=0; ia<NA; ia++) {
15644                     ProcessRecord r = procs.valueAt(ia);
15645                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15646                         continue;
15647                     }
15648                     if (!needSep) {
15649                         pw.println("  All known processes:");
15650                         needSep = true;
15651                         printedAnything = true;
15652                     }
15653                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15654                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15655                         pw.print(" "); pw.println(r);
15656                     r.dump(pw, "    ");
15657                     if (r.persistent) {
15658                         numPers++;
15659                     }
15660                 }
15661             }
15662         }
15663
15664         if (mIsolatedProcesses.size() > 0) {
15665             boolean printed = false;
15666             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15667                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15668                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15669                     continue;
15670                 }
15671                 if (!printed) {
15672                     if (needSep) {
15673                         pw.println();
15674                     }
15675                     pw.println("  Isolated process list (sorted by uid):");
15676                     printedAnything = true;
15677                     printed = true;
15678                     needSep = true;
15679                 }
15680                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15681                 pw.println(r);
15682             }
15683         }
15684
15685         if (mActiveInstrumentation.size() > 0) {
15686             boolean printed = false;
15687             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15688                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15689                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15690                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15691                     continue;
15692                 }
15693                 if (!printed) {
15694                     if (needSep) {
15695                         pw.println();
15696                     }
15697                     pw.println("  Active instrumentation:");
15698                     printedAnything = true;
15699                     printed = true;
15700                     needSep = true;
15701                 }
15702                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15703                 pw.println(ai);
15704                 ai.dump(pw, "      ");
15705             }
15706         }
15707
15708         if (mActiveUids.size() > 0) {
15709             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15710                 printedAnything = needSep = true;
15711             }
15712         }
15713         if (dumpAll) {
15714             if (mValidateUids.size() > 0) {
15715                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15716                     printedAnything = needSep = true;
15717                 }
15718             }
15719         }
15720
15721         if (mLruProcesses.size() > 0) {
15722             if (needSep) {
15723                 pw.println();
15724             }
15725             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15726                     pw.print(" total, non-act at ");
15727                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15728                     pw.print(", non-svc at ");
15729                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15730                     pw.println("):");
15731             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15732             needSep = true;
15733             printedAnything = true;
15734         }
15735
15736         if (dumpAll || dumpPackage != null) {
15737             synchronized (mPidsSelfLocked) {
15738                 boolean printed = false;
15739                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15740                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15741                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15742                         continue;
15743                     }
15744                     if (!printed) {
15745                         if (needSep) pw.println();
15746                         needSep = true;
15747                         pw.println("  PID mappings:");
15748                         printed = true;
15749                         printedAnything = true;
15750                     }
15751                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15752                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15753                 }
15754             }
15755         }
15756
15757         if (mImportantProcesses.size() > 0) {
15758             synchronized (mPidsSelfLocked) {
15759                 boolean printed = false;
15760                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15761                     ProcessRecord r = mPidsSelfLocked.get(
15762                             mImportantProcesses.valueAt(i).pid);
15763                     if (dumpPackage != null && (r == null
15764                             || !r.pkgList.containsKey(dumpPackage))) {
15765                         continue;
15766                     }
15767                     if (!printed) {
15768                         if (needSep) pw.println();
15769                         needSep = true;
15770                         pw.println("  Foreground Processes:");
15771                         printed = true;
15772                         printedAnything = true;
15773                     }
15774                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15775                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15776                 }
15777             }
15778         }
15779
15780         if (mPersistentStartingProcesses.size() > 0) {
15781             if (needSep) pw.println();
15782             needSep = true;
15783             printedAnything = true;
15784             pw.println("  Persisent processes that are starting:");
15785             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15786                     "Starting Norm", "Restarting PERS", dumpPackage);
15787         }
15788
15789         if (mRemovedProcesses.size() > 0) {
15790             if (needSep) pw.println();
15791             needSep = true;
15792             printedAnything = true;
15793             pw.println("  Processes that are being removed:");
15794             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15795                     "Removed Norm", "Removed PERS", dumpPackage);
15796         }
15797
15798         if (mProcessesOnHold.size() > 0) {
15799             if (needSep) pw.println();
15800             needSep = true;
15801             printedAnything = true;
15802             pw.println("  Processes that are on old until the system is ready:");
15803             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15804                     "OnHold Norm", "OnHold PERS", dumpPackage);
15805         }
15806
15807         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15808
15809         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15810         if (needSep) {
15811             printedAnything = true;
15812         }
15813
15814         if (dumpPackage == null) {
15815             pw.println();
15816             needSep = false;
15817             mUserController.dump(pw, dumpAll);
15818         }
15819         if (mHomeProcess != null && (dumpPackage == null
15820                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15821             if (needSep) {
15822                 pw.println();
15823                 needSep = false;
15824             }
15825             pw.println("  mHomeProcess: " + mHomeProcess);
15826         }
15827         if (mPreviousProcess != null && (dumpPackage == null
15828                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15829             if (needSep) {
15830                 pw.println();
15831                 needSep = false;
15832             }
15833             pw.println("  mPreviousProcess: " + mPreviousProcess);
15834         }
15835         if (dumpAll) {
15836             StringBuilder sb = new StringBuilder(128);
15837             sb.append("  mPreviousProcessVisibleTime: ");
15838             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15839             pw.println(sb);
15840         }
15841         if (mHeavyWeightProcess != null && (dumpPackage == null
15842                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15843             if (needSep) {
15844                 pw.println();
15845                 needSep = false;
15846             }
15847             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15848         }
15849         if (dumpPackage == null) {
15850             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15851             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15852         }
15853         if (dumpAll) {
15854             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15855             if (mCompatModePackages.getPackages().size() > 0) {
15856                 boolean printed = false;
15857                 for (Map.Entry<String, Integer> entry
15858                         : mCompatModePackages.getPackages().entrySet()) {
15859                     String pkg = entry.getKey();
15860                     int mode = entry.getValue();
15861                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15862                         continue;
15863                     }
15864                     if (!printed) {
15865                         pw.println("  mScreenCompatPackages:");
15866                         printed = true;
15867                     }
15868                     pw.print("    "); pw.print(pkg); pw.print(": ");
15869                             pw.print(mode); pw.println();
15870                 }
15871             }
15872             final int NI = mUidObservers.getRegisteredCallbackCount();
15873             boolean printed = false;
15874             for (int i=0; i<NI; i++) {
15875                 final UidObserverRegistration reg = (UidObserverRegistration)
15876                         mUidObservers.getRegisteredCallbackCookie(i);
15877                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15878                     if (!printed) {
15879                         pw.println("  mUidObservers:");
15880                         printed = true;
15881                     }
15882                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15883                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15884                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15885                         pw.print(" IDLE");
15886                     }
15887                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15888                         pw.print(" ACT" );
15889                     }
15890                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15891                         pw.print(" GONE");
15892                     }
15893                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15894                         pw.print(" STATE");
15895                         pw.print(" (cut="); pw.print(reg.cutpoint);
15896                         pw.print(")");
15897                     }
15898                     pw.println();
15899                     if (reg.lastProcStates != null) {
15900                         final int NJ = reg.lastProcStates.size();
15901                         for (int j=0; j<NJ; j++) {
15902                             pw.print("      Last ");
15903                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15904                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15905                         }
15906                     }
15907                 }
15908             }
15909             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15910             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15911             if (mPendingTempWhitelist.size() > 0) {
15912                 pw.println("  mPendingTempWhitelist:");
15913                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15914                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15915                     pw.print("    ");
15916                     UserHandle.formatUid(pw, ptw.targetUid);
15917                     pw.print(": ");
15918                     TimeUtils.formatDuration(ptw.duration, pw);
15919                     pw.print(" ");
15920                     pw.println(ptw.tag);
15921                 }
15922             }
15923         }
15924         if (dumpPackage == null) {
15925             pw.println("  mWakefulness="
15926                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15927             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15928             pw.println("  mSleeping=" + mSleeping);
15929             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15930             if (mRunningVoice != null) {
15931                 pw.println("  mRunningVoice=" + mRunningVoice);
15932                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15933             }
15934         }
15935         pw.println("  mVrController=" + mVrController);
15936         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15937                 || mOrigWaitForDebugger) {
15938             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15939                     || dumpPackage.equals(mOrigDebugApp)) {
15940                 if (needSep) {
15941                     pw.println();
15942                     needSep = false;
15943                 }
15944                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15945                         + " mDebugTransient=" + mDebugTransient
15946                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15947             }
15948         }
15949         if (mCurAppTimeTracker != null) {
15950             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15951         }
15952         if (mMemWatchProcesses.getMap().size() > 0) {
15953             pw.println("  Mem watch processes:");
15954             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15955                     = mMemWatchProcesses.getMap();
15956             for (int i=0; i<procs.size(); i++) {
15957                 final String proc = procs.keyAt(i);
15958                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15959                 for (int j=0; j<uids.size(); j++) {
15960                     if (needSep) {
15961                         pw.println();
15962                         needSep = false;
15963                     }
15964                     StringBuilder sb = new StringBuilder();
15965                     sb.append("    ").append(proc).append('/');
15966                     UserHandle.formatUid(sb, uids.keyAt(j));
15967                     Pair<Long, String> val = uids.valueAt(j);
15968                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15969                     if (val.second != null) {
15970                         sb.append(", report to ").append(val.second);
15971                     }
15972                     pw.println(sb.toString());
15973                 }
15974             }
15975             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15976             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15977             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15978                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15979         }
15980         if (mTrackAllocationApp != null) {
15981             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15982                 if (needSep) {
15983                     pw.println();
15984                     needSep = false;
15985                 }
15986                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15987             }
15988         }
15989         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
15990                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
15991             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
15992                 if (needSep) {
15993                     pw.println();
15994                     needSep = false;
15995                 }
15996                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
15997                 if (mProfilerInfo != null) {
15998                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
15999                             mProfilerInfo.profileFd);
16000                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16001                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16002                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16003                     pw.println("  mProfileType=" + mProfileType);
16004                 }
16005             }
16006         }
16007         if (mNativeDebuggingApp != null) {
16008             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16009                 if (needSep) {
16010                     pw.println();
16011                     needSep = false;
16012                 }
16013                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16014             }
16015         }
16016         if (dumpPackage == null) {
16017             if (mAlwaysFinishActivities) {
16018                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16019             }
16020             if (mController != null) {
16021                 pw.println("  mController=" + mController
16022                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16023             }
16024             if (dumpAll) {
16025                 pw.println("  Total persistent processes: " + numPers);
16026                 pw.println("  mProcessesReady=" + mProcessesReady
16027                         + " mSystemReady=" + mSystemReady
16028                         + " mBooted=" + mBooted
16029                         + " mFactoryTest=" + mFactoryTest);
16030                 pw.println("  mBooting=" + mBooting
16031                         + " mCallFinishBooting=" + mCallFinishBooting
16032                         + " mBootAnimationComplete=" + mBootAnimationComplete);
16033                 pw.print("  mLastPowerCheckUptime=");
16034                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16035                         pw.println("");
16036                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16037                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16038                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16039                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16040                         + " (" + mLruProcesses.size() + " total)"
16041                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16042                         + " mNumServiceProcs=" + mNumServiceProcs
16043                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16044                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16045                         + " mLastMemoryLevel=" + mLastMemoryLevel
16046                         + " mLastNumProcesses=" + mLastNumProcesses);
16047                 long now = SystemClock.uptimeMillis();
16048                 pw.print("  mLastIdleTime=");
16049                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
16050                         pw.print(" mLowRamSinceLastIdle=");
16051                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16052                         pw.println();
16053             }
16054         }
16055
16056         if (!printedAnything) {
16057             pw.println("  (nothing)");
16058         }
16059     }
16060
16061     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16062             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16063         if (mProcessesToGc.size() > 0) {
16064             boolean printed = false;
16065             long now = SystemClock.uptimeMillis();
16066             for (int i=0; i<mProcessesToGc.size(); i++) {
16067                 ProcessRecord proc = mProcessesToGc.get(i);
16068                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16069                     continue;
16070                 }
16071                 if (!printed) {
16072                     if (needSep) pw.println();
16073                     needSep = true;
16074                     pw.println("  Processes that are waiting to GC:");
16075                     printed = true;
16076                 }
16077                 pw.print("    Process "); pw.println(proc);
16078                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16079                         pw.print(", last gced=");
16080                         pw.print(now-proc.lastRequestedGc);
16081                         pw.print(" ms ago, last lowMem=");
16082                         pw.print(now-proc.lastLowMemory);
16083                         pw.println(" ms ago");
16084
16085             }
16086         }
16087         return needSep;
16088     }
16089
16090     void printOomLevel(PrintWriter pw, String name, int adj) {
16091         pw.print("    ");
16092         if (adj >= 0) {
16093             pw.print(' ');
16094             if (adj < 10) pw.print(' ');
16095         } else {
16096             if (adj > -10) pw.print(' ');
16097         }
16098         pw.print(adj);
16099         pw.print(": ");
16100         pw.print(name);
16101         pw.print(" (");
16102         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16103         pw.println(")");
16104     }
16105
16106     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16107             int opti, boolean dumpAll) {
16108         boolean needSep = false;
16109
16110         if (mLruProcesses.size() > 0) {
16111             if (needSep) pw.println();
16112             needSep = true;
16113             pw.println("  OOM levels:");
16114             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16115             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16116             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16117             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16118             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16119             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16120             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16121             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16122             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16123             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16124             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16125             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16126             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16127             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16128
16129             if (needSep) pw.println();
16130             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16131                     pw.print(" total, non-act at ");
16132                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16133                     pw.print(", non-svc at ");
16134                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16135                     pw.println("):");
16136             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16137             needSep = true;
16138         }
16139
16140         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16141
16142         pw.println();
16143         pw.println("  mHomeProcess: " + mHomeProcess);
16144         pw.println("  mPreviousProcess: " + mPreviousProcess);
16145         if (mHeavyWeightProcess != null) {
16146             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16147         }
16148
16149         return true;
16150     }
16151
16152     /**
16153      * There are three ways to call this:
16154      *  - no provider specified: dump all the providers
16155      *  - a flattened component name that matched an existing provider was specified as the
16156      *    first arg: dump that one provider
16157      *  - the first arg isn't the flattened component name of an existing provider:
16158      *    dump all providers whose component contains the first arg as a substring
16159      */
16160     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16161             int opti, boolean dumpAll) {
16162         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16163     }
16164
16165     static class ItemMatcher {
16166         ArrayList<ComponentName> components;
16167         ArrayList<String> strings;
16168         ArrayList<Integer> objects;
16169         boolean all;
16170
16171         ItemMatcher() {
16172             all = true;
16173         }
16174
16175         void build(String name) {
16176             ComponentName componentName = ComponentName.unflattenFromString(name);
16177             if (componentName != null) {
16178                 if (components == null) {
16179                     components = new ArrayList<ComponentName>();
16180                 }
16181                 components.add(componentName);
16182                 all = false;
16183             } else {
16184                 int objectId = 0;
16185                 // Not a '/' separated full component name; maybe an object ID?
16186                 try {
16187                     objectId = Integer.parseInt(name, 16);
16188                     if (objects == null) {
16189                         objects = new ArrayList<Integer>();
16190                     }
16191                     objects.add(objectId);
16192                     all = false;
16193                 } catch (RuntimeException e) {
16194                     // Not an integer; just do string match.
16195                     if (strings == null) {
16196                         strings = new ArrayList<String>();
16197                     }
16198                     strings.add(name);
16199                     all = false;
16200                 }
16201             }
16202         }
16203
16204         int build(String[] args, int opti) {
16205             for (; opti<args.length; opti++) {
16206                 String name = args[opti];
16207                 if ("--".equals(name)) {
16208                     return opti+1;
16209                 }
16210                 build(name);
16211             }
16212             return opti;
16213         }
16214
16215         boolean match(Object object, ComponentName comp) {
16216             if (all) {
16217                 return true;
16218             }
16219             if (components != null) {
16220                 for (int i=0; i<components.size(); i++) {
16221                     if (components.get(i).equals(comp)) {
16222                         return true;
16223                     }
16224                 }
16225             }
16226             if (objects != null) {
16227                 for (int i=0; i<objects.size(); i++) {
16228                     if (System.identityHashCode(object) == objects.get(i)) {
16229                         return true;
16230                     }
16231                 }
16232             }
16233             if (strings != null) {
16234                 String flat = comp.flattenToString();
16235                 for (int i=0; i<strings.size(); i++) {
16236                     if (flat.contains(strings.get(i))) {
16237                         return true;
16238                     }
16239                 }
16240             }
16241             return false;
16242         }
16243     }
16244
16245     /**
16246      * There are three things that cmd can be:
16247      *  - a flattened component name that matches an existing activity
16248      *  - the cmd arg isn't the flattened component name of an existing activity:
16249      *    dump all activity whose component contains the cmd as a substring
16250      *  - A hex number of the ActivityRecord object instance.
16251      *
16252      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16253      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16254      */
16255     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16256             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16257         ArrayList<ActivityRecord> activities;
16258
16259         synchronized (this) {
16260             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16261                     dumpFocusedStackOnly);
16262         }
16263
16264         if (activities.size() <= 0) {
16265             return false;
16266         }
16267
16268         String[] newArgs = new String[args.length - opti];
16269         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16270
16271         TaskRecord lastTask = null;
16272         boolean needSep = false;
16273         for (int i=activities.size()-1; i>=0; i--) {
16274             ActivityRecord r = activities.get(i);
16275             if (needSep) {
16276                 pw.println();
16277             }
16278             needSep = true;
16279             synchronized (this) {
16280                 final TaskRecord task = r.getTask();
16281                 if (lastTask != task) {
16282                     lastTask = task;
16283                     pw.print("TASK "); pw.print(lastTask.affinity);
16284                             pw.print(" id="); pw.print(lastTask.taskId);
16285                             pw.print(" userId="); pw.println(lastTask.userId);
16286                     if (dumpAll) {
16287                         lastTask.dump(pw, "  ");
16288                     }
16289                 }
16290             }
16291             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16292         }
16293         return true;
16294     }
16295
16296     /**
16297      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16298      * there is a thread associated with the activity.
16299      */
16300     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16301             final ActivityRecord r, String[] args, boolean dumpAll) {
16302         String innerPrefix = prefix + "  ";
16303         synchronized (this) {
16304             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16305                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16306                     pw.print(" pid=");
16307                     if (r.app != null) pw.println(r.app.pid);
16308                     else pw.println("(not running)");
16309             if (dumpAll) {
16310                 r.dump(pw, innerPrefix);
16311             }
16312         }
16313         if (r.app != null && r.app.thread != null) {
16314             // flush anything that is already in the PrintWriter since the thread is going
16315             // to write to the file descriptor directly
16316             pw.flush();
16317             try {
16318                 TransferPipe tp = new TransferPipe();
16319                 try {
16320                     r.app.thread.dumpActivity(tp.getWriteFd(),
16321                             r.appToken, innerPrefix, args);
16322                     tp.go(fd);
16323                 } finally {
16324                     tp.kill();
16325                 }
16326             } catch (IOException e) {
16327                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16328             } catch (RemoteException e) {
16329                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16330             }
16331         }
16332     }
16333
16334     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16335             int opti, boolean dumpAll, String dumpPackage) {
16336         boolean needSep = false;
16337         boolean onlyHistory = false;
16338         boolean printedAnything = false;
16339
16340         if ("history".equals(dumpPackage)) {
16341             if (opti < args.length && "-s".equals(args[opti])) {
16342                 dumpAll = false;
16343             }
16344             onlyHistory = true;
16345             dumpPackage = null;
16346         }
16347
16348         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16349         if (!onlyHistory && dumpAll) {
16350             if (mRegisteredReceivers.size() > 0) {
16351                 boolean printed = false;
16352                 Iterator it = mRegisteredReceivers.values().iterator();
16353                 while (it.hasNext()) {
16354                     ReceiverList r = (ReceiverList)it.next();
16355                     if (dumpPackage != null && (r.app == null ||
16356                             !dumpPackage.equals(r.app.info.packageName))) {
16357                         continue;
16358                     }
16359                     if (!printed) {
16360                         pw.println("  Registered Receivers:");
16361                         needSep = true;
16362                         printed = true;
16363                         printedAnything = true;
16364                     }
16365                     pw.print("  * "); pw.println(r);
16366                     r.dump(pw, "    ");
16367                 }
16368             }
16369
16370             if (mReceiverResolver.dump(pw, needSep ?
16371                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16372                     "    ", dumpPackage, false, false)) {
16373                 needSep = true;
16374                 printedAnything = true;
16375             }
16376         }
16377
16378         for (BroadcastQueue q : mBroadcastQueues) {
16379             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16380             printedAnything |= needSep;
16381         }
16382
16383         needSep = true;
16384
16385         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16386             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16387                 if (needSep) {
16388                     pw.println();
16389                 }
16390                 needSep = true;
16391                 printedAnything = true;
16392                 pw.print("  Sticky broadcasts for user ");
16393                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16394                 StringBuilder sb = new StringBuilder(128);
16395                 for (Map.Entry<String, ArrayList<Intent>> ent
16396                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16397                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16398                     if (dumpAll) {
16399                         pw.println(":");
16400                         ArrayList<Intent> intents = ent.getValue();
16401                         final int N = intents.size();
16402                         for (int i=0; i<N; i++) {
16403                             sb.setLength(0);
16404                             sb.append("    Intent: ");
16405                             intents.get(i).toShortString(sb, false, true, false, false);
16406                             pw.println(sb.toString());
16407                             Bundle bundle = intents.get(i).getExtras();
16408                             if (bundle != null) {
16409                                 pw.print("      ");
16410                                 pw.println(bundle.toString());
16411                             }
16412                         }
16413                     } else {
16414                         pw.println("");
16415                     }
16416                 }
16417             }
16418         }
16419
16420         if (!onlyHistory && dumpAll) {
16421             pw.println();
16422             for (BroadcastQueue queue : mBroadcastQueues) {
16423                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16424                         + queue.mBroadcastsScheduled);
16425             }
16426             pw.println("  mHandler:");
16427             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16428             needSep = true;
16429             printedAnything = true;
16430         }
16431
16432         if (!printedAnything) {
16433             pw.println("  (nothing)");
16434         }
16435     }
16436
16437     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16438             int opti, boolean dumpAll, String dumpPackage) {
16439         if (mCurBroadcastStats == null) {
16440             return;
16441         }
16442
16443         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16444         final long now = SystemClock.elapsedRealtime();
16445         if (mLastBroadcastStats != null) {
16446             pw.print("  Last stats (from ");
16447             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16448             pw.print(" to ");
16449             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16450             pw.print(", ");
16451             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16452                     - mLastBroadcastStats.mStartUptime, pw);
16453             pw.println(" uptime):");
16454             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16455                 pw.println("    (nothing)");
16456             }
16457             pw.println();
16458         }
16459         pw.print("  Current stats (from ");
16460         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16461         pw.print(" to now, ");
16462         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16463                 - mCurBroadcastStats.mStartUptime, pw);
16464         pw.println(" uptime):");
16465         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16466             pw.println("    (nothing)");
16467         }
16468     }
16469
16470     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16471             int opti, boolean fullCheckin, String dumpPackage) {
16472         if (mCurBroadcastStats == null) {
16473             return;
16474         }
16475
16476         if (mLastBroadcastStats != null) {
16477             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16478             if (fullCheckin) {
16479                 mLastBroadcastStats = null;
16480                 return;
16481             }
16482         }
16483         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16484         if (fullCheckin) {
16485             mCurBroadcastStats = null;
16486         }
16487     }
16488
16489     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16490             int opti, boolean dumpAll, String dumpPackage) {
16491         boolean needSep;
16492         boolean printedAnything = false;
16493
16494         ItemMatcher matcher = new ItemMatcher();
16495         matcher.build(args, opti);
16496
16497         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16498
16499         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16500         printedAnything |= needSep;
16501
16502         if (mLaunchingProviders.size() > 0) {
16503             boolean printed = false;
16504             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16505                 ContentProviderRecord r = mLaunchingProviders.get(i);
16506                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16507                     continue;
16508                 }
16509                 if (!printed) {
16510                     if (needSep) pw.println();
16511                     needSep = true;
16512                     pw.println("  Launching content providers:");
16513                     printed = true;
16514                     printedAnything = true;
16515                 }
16516                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16517                         pw.println(r);
16518             }
16519         }
16520
16521         if (!printedAnything) {
16522             pw.println("  (nothing)");
16523         }
16524     }
16525
16526     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16527             int opti, boolean dumpAll, String dumpPackage) {
16528         boolean needSep = false;
16529         boolean printedAnything = false;
16530
16531         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16532
16533         if (mGrantedUriPermissions.size() > 0) {
16534             boolean printed = false;
16535             int dumpUid = -2;
16536             if (dumpPackage != null) {
16537                 try {
16538                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16539                             MATCH_ANY_USER, 0);
16540                 } catch (NameNotFoundException e) {
16541                     dumpUid = -1;
16542                 }
16543             }
16544             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16545                 int uid = mGrantedUriPermissions.keyAt(i);
16546                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16547                     continue;
16548                 }
16549                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16550                 if (!printed) {
16551                     if (needSep) pw.println();
16552                     needSep = true;
16553                     pw.println("  Granted Uri Permissions:");
16554                     printed = true;
16555                     printedAnything = true;
16556                 }
16557                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16558                 for (UriPermission perm : perms.values()) {
16559                     pw.print("    "); pw.println(perm);
16560                     if (dumpAll) {
16561                         perm.dump(pw, "      ");
16562                     }
16563                 }
16564             }
16565         }
16566
16567         if (!printedAnything) {
16568             pw.println("  (nothing)");
16569         }
16570     }
16571
16572     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16573             int opti, boolean dumpAll, String dumpPackage) {
16574         boolean printed = false;
16575
16576         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16577
16578         if (mIntentSenderRecords.size() > 0) {
16579             // Organize these by package name, so they are easier to read.
16580             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16581             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16582             final Iterator<WeakReference<PendingIntentRecord>> it
16583                     = mIntentSenderRecords.values().iterator();
16584             while (it.hasNext()) {
16585                 WeakReference<PendingIntentRecord> ref = it.next();
16586                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16587                 if (rec == null) {
16588                     weakRefs.add(ref);
16589                     continue;
16590                 }
16591                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16592                     continue;
16593                 }
16594                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16595                 if (list == null) {
16596                     list = new ArrayList<>();
16597                     byPackage.put(rec.key.packageName, list);
16598                 }
16599                 list.add(rec);
16600             }
16601             for (int i = 0; i < byPackage.size(); i++) {
16602                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16603                 printed = true;
16604                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16605                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16606                 for (int j = 0; j < intents.size(); j++) {
16607                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16608                     if (dumpAll) {
16609                         intents.get(j).dump(pw, "      ");
16610                     }
16611                 }
16612             }
16613             if (weakRefs.size() > 0) {
16614                 printed = true;
16615                 pw.println("  * WEAK REFS:");
16616                 for (int i = 0; i < weakRefs.size(); i++) {
16617                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16618                 }
16619             }
16620         }
16621
16622         if (!printed) {
16623             pw.println("  (nothing)");
16624         }
16625     }
16626
16627     private static final int dumpProcessList(PrintWriter pw,
16628             ActivityManagerService service, List list,
16629             String prefix, String normalLabel, String persistentLabel,
16630             String dumpPackage) {
16631         int numPers = 0;
16632         final int N = list.size()-1;
16633         for (int i=N; i>=0; i--) {
16634             ProcessRecord r = (ProcessRecord)list.get(i);
16635             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16636                 continue;
16637             }
16638             pw.println(String.format("%s%s #%2d: %s",
16639                     prefix, (r.persistent ? persistentLabel : normalLabel),
16640                     i, r.toString()));
16641             if (r.persistent) {
16642                 numPers++;
16643             }
16644         }
16645         return numPers;
16646     }
16647
16648     private static final boolean dumpProcessOomList(PrintWriter pw,
16649             ActivityManagerService service, List<ProcessRecord> origList,
16650             String prefix, String normalLabel, String persistentLabel,
16651             boolean inclDetails, String dumpPackage) {
16652
16653         ArrayList<Pair<ProcessRecord, Integer>> list
16654                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16655         for (int i=0; i<origList.size(); i++) {
16656             ProcessRecord r = origList.get(i);
16657             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16658                 continue;
16659             }
16660             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16661         }
16662
16663         if (list.size() <= 0) {
16664             return false;
16665         }
16666
16667         Comparator<Pair<ProcessRecord, Integer>> comparator
16668                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16669             @Override
16670             public int compare(Pair<ProcessRecord, Integer> object1,
16671                     Pair<ProcessRecord, Integer> object2) {
16672                 if (object1.first.setAdj != object2.first.setAdj) {
16673                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16674                 }
16675                 if (object1.first.setProcState != object2.first.setProcState) {
16676                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16677                 }
16678                 if (object1.second.intValue() != object2.second.intValue()) {
16679                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16680                 }
16681                 return 0;
16682             }
16683         };
16684
16685         Collections.sort(list, comparator);
16686
16687         final long curUptime = SystemClock.uptimeMillis();
16688         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16689
16690         for (int i=list.size()-1; i>=0; i--) {
16691             ProcessRecord r = list.get(i).first;
16692             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16693             char schedGroup;
16694             switch (r.setSchedGroup) {
16695                 case ProcessList.SCHED_GROUP_BACKGROUND:
16696                     schedGroup = 'B';
16697                     break;
16698                 case ProcessList.SCHED_GROUP_DEFAULT:
16699                     schedGroup = 'F';
16700                     break;
16701                 case ProcessList.SCHED_GROUP_TOP_APP:
16702                     schedGroup = 'T';
16703                     break;
16704                 default:
16705                     schedGroup = '?';
16706                     break;
16707             }
16708             char foreground;
16709             if (r.foregroundActivities) {
16710                 foreground = 'A';
16711             } else if (r.foregroundServices) {
16712                 foreground = 'S';
16713             } else {
16714                 foreground = ' ';
16715             }
16716             String procState = ProcessList.makeProcStateString(r.curProcState);
16717             pw.print(prefix);
16718             pw.print(r.persistent ? persistentLabel : normalLabel);
16719             pw.print(" #");
16720             int num = (origList.size()-1)-list.get(i).second;
16721             if (num < 10) pw.print(' ');
16722             pw.print(num);
16723             pw.print(": ");
16724             pw.print(oomAdj);
16725             pw.print(' ');
16726             pw.print(schedGroup);
16727             pw.print('/');
16728             pw.print(foreground);
16729             pw.print('/');
16730             pw.print(procState);
16731             pw.print(" trm:");
16732             if (r.trimMemoryLevel < 10) pw.print(' ');
16733             pw.print(r.trimMemoryLevel);
16734             pw.print(' ');
16735             pw.print(r.toShortString());
16736             pw.print(" (");
16737             pw.print(r.adjType);
16738             pw.println(')');
16739             if (r.adjSource != null || r.adjTarget != null) {
16740                 pw.print(prefix);
16741                 pw.print("    ");
16742                 if (r.adjTarget instanceof ComponentName) {
16743                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16744                 } else if (r.adjTarget != null) {
16745                     pw.print(r.adjTarget.toString());
16746                 } else {
16747                     pw.print("{null}");
16748                 }
16749                 pw.print("<=");
16750                 if (r.adjSource instanceof ProcessRecord) {
16751                     pw.print("Proc{");
16752                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16753                     pw.println("}");
16754                 } else if (r.adjSource != null) {
16755                     pw.println(r.adjSource.toString());
16756                 } else {
16757                     pw.println("{null}");
16758                 }
16759             }
16760             if (inclDetails) {
16761                 pw.print(prefix);
16762                 pw.print("    ");
16763                 pw.print("oom: max="); pw.print(r.maxAdj);
16764                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16765                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16766                 pw.print(" cur="); pw.print(r.curAdj);
16767                 pw.print(" set="); pw.println(r.setAdj);
16768                 pw.print(prefix);
16769                 pw.print("    ");
16770                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16771                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16772                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16773                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16774                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16775                 pw.println();
16776                 pw.print(prefix);
16777                 pw.print("    ");
16778                 pw.print("cached="); pw.print(r.cached);
16779                 pw.print(" empty="); pw.print(r.empty);
16780                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16781
16782                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16783                     if (r.lastCpuTime != 0) {
16784                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16785                         pw.print(prefix);
16786                         pw.print("    ");
16787                         pw.print("run cpu over ");
16788                         TimeUtils.formatDuration(uptimeSince, pw);
16789                         pw.print(" used ");
16790                         TimeUtils.formatDuration(timeUsed, pw);
16791                         pw.print(" (");
16792                         pw.print((timeUsed*100)/uptimeSince);
16793                         pw.println("%)");
16794                     }
16795                 }
16796             }
16797         }
16798         return true;
16799     }
16800
16801     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16802             String[] args) {
16803         ArrayList<ProcessRecord> procs;
16804         synchronized (this) {
16805             if (args != null && args.length > start
16806                     && args[start].charAt(0) != '-') {
16807                 procs = new ArrayList<ProcessRecord>();
16808                 int pid = -1;
16809                 try {
16810                     pid = Integer.parseInt(args[start]);
16811                 } catch (NumberFormatException e) {
16812                 }
16813                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16814                     ProcessRecord proc = mLruProcesses.get(i);
16815                     if (proc.pid == pid) {
16816                         procs.add(proc);
16817                     } else if (allPkgs && proc.pkgList != null
16818                             && proc.pkgList.containsKey(args[start])) {
16819                         procs.add(proc);
16820                     } else if (proc.processName.equals(args[start])) {
16821                         procs.add(proc);
16822                     }
16823                 }
16824                 if (procs.size() <= 0) {
16825                     return null;
16826                 }
16827             } else {
16828                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16829             }
16830         }
16831         return procs;
16832     }
16833
16834     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16835             PrintWriter pw, String[] args) {
16836         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16837         if (procs == null) {
16838             pw.println("No process found for: " + args[0]);
16839             return;
16840         }
16841
16842         long uptime = SystemClock.uptimeMillis();
16843         long realtime = SystemClock.elapsedRealtime();
16844         pw.println("Applications Graphics Acceleration Info:");
16845         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16846
16847         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16848             ProcessRecord r = procs.get(i);
16849             if (r.thread != null) {
16850                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16851                 pw.flush();
16852                 try {
16853                     TransferPipe tp = new TransferPipe();
16854                     try {
16855                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16856                         tp.go(fd);
16857                     } finally {
16858                         tp.kill();
16859                     }
16860                 } catch (IOException e) {
16861                     pw.println("Failure while dumping the app: " + r);
16862                     pw.flush();
16863                 } catch (RemoteException e) {
16864                     pw.println("Got a RemoteException while dumping the app " + r);
16865                     pw.flush();
16866                 }
16867             }
16868         }
16869     }
16870
16871     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16872         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16873         if (procs == null) {
16874             pw.println("No process found for: " + args[0]);
16875             return;
16876         }
16877
16878         pw.println("Applications Database Info:");
16879
16880         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16881             ProcessRecord r = procs.get(i);
16882             if (r.thread != null) {
16883                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16884                 pw.flush();
16885                 try {
16886                     TransferPipe tp = new TransferPipe();
16887                     try {
16888                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16889                         tp.go(fd);
16890                     } finally {
16891                         tp.kill();
16892                     }
16893                 } catch (IOException e) {
16894                     pw.println("Failure while dumping the app: " + r);
16895                     pw.flush();
16896                 } catch (RemoteException e) {
16897                     pw.println("Got a RemoteException while dumping the app " + r);
16898                     pw.flush();
16899                 }
16900             }
16901         }
16902     }
16903
16904     final static class MemItem {
16905         final boolean isProc;
16906         final String label;
16907         final String shortLabel;
16908         final long pss;
16909         final long swapPss;
16910         final int id;
16911         final boolean hasActivities;
16912         ArrayList<MemItem> subitems;
16913
16914         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16915                 boolean _hasActivities) {
16916             isProc = true;
16917             label = _label;
16918             shortLabel = _shortLabel;
16919             pss = _pss;
16920             swapPss = _swapPss;
16921             id = _id;
16922             hasActivities = _hasActivities;
16923         }
16924
16925         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16926             isProc = false;
16927             label = _label;
16928             shortLabel = _shortLabel;
16929             pss = _pss;
16930             swapPss = _swapPss;
16931             id = _id;
16932             hasActivities = false;
16933         }
16934     }
16935
16936     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16937             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16938         if (sort && !isCompact) {
16939             Collections.sort(items, new Comparator<MemItem>() {
16940                 @Override
16941                 public int compare(MemItem lhs, MemItem rhs) {
16942                     if (lhs.pss < rhs.pss) {
16943                         return 1;
16944                     } else if (lhs.pss > rhs.pss) {
16945                         return -1;
16946                     }
16947                     return 0;
16948                 }
16949             });
16950         }
16951
16952         for (int i=0; i<items.size(); i++) {
16953             MemItem mi = items.get(i);
16954             if (!isCompact) {
16955                 if (dumpSwapPss) {
16956                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16957                             mi.label, stringifyKBSize(mi.swapPss));
16958                 } else {
16959                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16960                 }
16961             } else if (mi.isProc) {
16962                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16963                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16964                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16965                 pw.println(mi.hasActivities ? ",a" : ",e");
16966             } else {
16967                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16968                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16969             }
16970             if (mi.subitems != null) {
16971                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16972                         true, isCompact, dumpSwapPss);
16973             }
16974         }
16975     }
16976
16977     // These are in KB.
16978     static final long[] DUMP_MEM_BUCKETS = new long[] {
16979         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16980         120*1024, 160*1024, 200*1024,
16981         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16982         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16983     };
16984
16985     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16986             boolean stackLike) {
16987         int start = label.lastIndexOf('.');
16988         if (start >= 0) start++;
16989         else start = 0;
16990         int end = label.length();
16991         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
16992             if (DUMP_MEM_BUCKETS[i] >= memKB) {
16993                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
16994                 out.append(bucket);
16995                 out.append(stackLike ? "MB." : "MB ");
16996                 out.append(label, start, end);
16997                 return;
16998             }
16999         }
17000         out.append(memKB/1024);
17001         out.append(stackLike ? "MB." : "MB ");
17002         out.append(label, start, end);
17003     }
17004
17005     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17006             ProcessList.NATIVE_ADJ,
17007             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17008             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17009             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17010             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17011             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17012             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17013     };
17014     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17015             "Native",
17016             "System", "Persistent", "Persistent Service", "Foreground",
17017             "Visible", "Perceptible",
17018             "Heavy Weight", "Backup",
17019             "A Services", "Home",
17020             "Previous", "B Services", "Cached"
17021     };
17022     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17023             "native",
17024             "sys", "pers", "persvc", "fore",
17025             "vis", "percept",
17026             "heavy", "backup",
17027             "servicea", "home",
17028             "prev", "serviceb", "cached"
17029     };
17030
17031     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17032             long realtime, boolean isCheckinRequest, boolean isCompact) {
17033         if (isCompact) {
17034             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17035         }
17036         if (isCheckinRequest || isCompact) {
17037             // short checkin version
17038             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17039         } else {
17040             pw.println("Applications Memory Usage (in Kilobytes):");
17041             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17042         }
17043     }
17044
17045     private static final int KSM_SHARED = 0;
17046     private static final int KSM_SHARING = 1;
17047     private static final int KSM_UNSHARED = 2;
17048     private static final int KSM_VOLATILE = 3;
17049
17050     private final long[] getKsmInfo() {
17051         long[] longOut = new long[4];
17052         final int[] SINGLE_LONG_FORMAT = new int[] {
17053             PROC_SPACE_TERM| PROC_OUT_LONG
17054         };
17055         long[] longTmp = new long[1];
17056         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17057                 SINGLE_LONG_FORMAT, null, longTmp, null);
17058         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17059         longTmp[0] = 0;
17060         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17061                 SINGLE_LONG_FORMAT, null, longTmp, null);
17062         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17063         longTmp[0] = 0;
17064         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17065                 SINGLE_LONG_FORMAT, null, longTmp, null);
17066         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17067         longTmp[0] = 0;
17068         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17069                 SINGLE_LONG_FORMAT, null, longTmp, null);
17070         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17071         return longOut;
17072     }
17073
17074     private static String stringifySize(long size, int order) {
17075         Locale locale = Locale.US;
17076         switch (order) {
17077             case 1:
17078                 return String.format(locale, "%,13d", size);
17079             case 1024:
17080                 return String.format(locale, "%,9dK", size / 1024);
17081             case 1024 * 1024:
17082                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17083             case 1024 * 1024 * 1024:
17084                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17085             default:
17086                 throw new IllegalArgumentException("Invalid size order");
17087         }
17088     }
17089
17090     private static String stringifyKBSize(long size) {
17091         return stringifySize(size * 1024, 1024);
17092     }
17093
17094     // Update this version number in case you change the 'compact' format
17095     private static final int MEMINFO_COMPACT_VERSION = 1;
17096
17097     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17098             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17099         boolean dumpDetails = false;
17100         boolean dumpFullDetails = false;
17101         boolean dumpDalvik = false;
17102         boolean dumpSummaryOnly = false;
17103         boolean dumpUnreachable = false;
17104         boolean oomOnly = false;
17105         boolean isCompact = false;
17106         boolean localOnly = false;
17107         boolean packages = false;
17108         boolean isCheckinRequest = false;
17109         boolean dumpSwapPss = false;
17110
17111         int opti = 0;
17112         while (opti < args.length) {
17113             String opt = args[opti];
17114             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17115                 break;
17116             }
17117             opti++;
17118             if ("-a".equals(opt)) {
17119                 dumpDetails = true;
17120                 dumpFullDetails = true;
17121                 dumpDalvik = true;
17122                 dumpSwapPss = true;
17123             } else if ("-d".equals(opt)) {
17124                 dumpDalvik = true;
17125             } else if ("-c".equals(opt)) {
17126                 isCompact = true;
17127             } else if ("-s".equals(opt)) {
17128                 dumpDetails = true;
17129                 dumpSummaryOnly = true;
17130             } else if ("-S".equals(opt)) {
17131                 dumpSwapPss = true;
17132             } else if ("--unreachable".equals(opt)) {
17133                 dumpUnreachable = true;
17134             } else if ("--oom".equals(opt)) {
17135                 oomOnly = true;
17136             } else if ("--local".equals(opt)) {
17137                 localOnly = true;
17138             } else if ("--package".equals(opt)) {
17139                 packages = true;
17140             } else if ("--checkin".equals(opt)) {
17141                 isCheckinRequest = true;
17142
17143             } else if ("-h".equals(opt)) {
17144                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17145                 pw.println("  -a: include all available information for each process.");
17146                 pw.println("  -d: include dalvik details.");
17147                 pw.println("  -c: dump in a compact machine-parseable representation.");
17148                 pw.println("  -s: dump only summary of application memory usage.");
17149                 pw.println("  -S: dump also SwapPss.");
17150                 pw.println("  --oom: only show processes organized by oom adj.");
17151                 pw.println("  --local: only collect details locally, don't call process.");
17152                 pw.println("  --package: interpret process arg as package, dumping all");
17153                 pw.println("             processes that have loaded that package.");
17154                 pw.println("  --checkin: dump data for a checkin");
17155                 pw.println("If [process] is specified it can be the name or ");
17156                 pw.println("pid of a specific process to dump.");
17157                 return;
17158             } else {
17159                 pw.println("Unknown argument: " + opt + "; use -h for help");
17160             }
17161         }
17162
17163         long uptime = SystemClock.uptimeMillis();
17164         long realtime = SystemClock.elapsedRealtime();
17165         final long[] tmpLong = new long[1];
17166
17167         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17168         if (procs == null) {
17169             // No Java processes.  Maybe they want to print a native process.
17170             if (args != null && args.length > opti
17171                     && args[opti].charAt(0) != '-') {
17172                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17173                         = new ArrayList<ProcessCpuTracker.Stats>();
17174                 updateCpuStatsNow();
17175                 int findPid = -1;
17176                 try {
17177                     findPid = Integer.parseInt(args[opti]);
17178                 } catch (NumberFormatException e) {
17179                 }
17180                 synchronized (mProcessCpuTracker) {
17181                     final int N = mProcessCpuTracker.countStats();
17182                     for (int i=0; i<N; i++) {
17183                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17184                         if (st.pid == findPid || (st.baseName != null
17185                                 && st.baseName.equals(args[opti]))) {
17186                             nativeProcs.add(st);
17187                         }
17188                     }
17189                 }
17190                 if (nativeProcs.size() > 0) {
17191                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17192                             isCompact);
17193                     Debug.MemoryInfo mi = null;
17194                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17195                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17196                         final int pid = r.pid;
17197                         if (!isCheckinRequest && dumpDetails) {
17198                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17199                         }
17200                         if (mi == null) {
17201                             mi = new Debug.MemoryInfo();
17202                         }
17203                         if (dumpDetails || (!brief && !oomOnly)) {
17204                             Debug.getMemoryInfo(pid, mi);
17205                         } else {
17206                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17207                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17208                         }
17209                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17210                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17211                         if (isCheckinRequest) {
17212                             pw.println();
17213                         }
17214                     }
17215                     return;
17216                 }
17217             }
17218             pw.println("No process found for: " + args[opti]);
17219             return;
17220         }
17221
17222         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17223             dumpDetails = true;
17224         }
17225
17226         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17227
17228         String[] innerArgs = new String[args.length-opti];
17229         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17230
17231         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17232         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17233         long nativePss = 0;
17234         long nativeSwapPss = 0;
17235         long dalvikPss = 0;
17236         long dalvikSwapPss = 0;
17237         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17238                 EmptyArray.LONG;
17239         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17240                 EmptyArray.LONG;
17241         long otherPss = 0;
17242         long otherSwapPss = 0;
17243         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17244         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17245
17246         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17247         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17248         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17249                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17250
17251         long totalPss = 0;
17252         long totalSwapPss = 0;
17253         long cachedPss = 0;
17254         long cachedSwapPss = 0;
17255         boolean hasSwapPss = false;
17256
17257         Debug.MemoryInfo mi = null;
17258         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17259             final ProcessRecord r = procs.get(i);
17260             final IApplicationThread thread;
17261             final int pid;
17262             final int oomAdj;
17263             final boolean hasActivities;
17264             synchronized (this) {
17265                 thread = r.thread;
17266                 pid = r.pid;
17267                 oomAdj = r.getSetAdjWithServices();
17268                 hasActivities = r.activities.size() > 0;
17269             }
17270             if (thread != null) {
17271                 if (!isCheckinRequest && dumpDetails) {
17272                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17273                 }
17274                 if (mi == null) {
17275                     mi = new Debug.MemoryInfo();
17276                 }
17277                 if (dumpDetails || (!brief && !oomOnly)) {
17278                     Debug.getMemoryInfo(pid, mi);
17279                     hasSwapPss = mi.hasSwappedOutPss;
17280                 } else {
17281                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17282                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17283                 }
17284                 if (dumpDetails) {
17285                     if (localOnly) {
17286                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17287                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17288                         if (isCheckinRequest) {
17289                             pw.println();
17290                         }
17291                     } else {
17292                         pw.flush();
17293                         try {
17294                             TransferPipe tp = new TransferPipe();
17295                             try {
17296                                 thread.dumpMemInfo(tp.getWriteFd(),
17297                                         mi, isCheckinRequest, dumpFullDetails,
17298                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17299                                 tp.go(fd);
17300                             } finally {
17301                                 tp.kill();
17302                             }
17303                         } catch (IOException e) {
17304                             if (!isCheckinRequest) {
17305                                 pw.println("Got IoException! " + e);
17306                                 pw.flush();
17307                             }
17308                         } catch (RemoteException e) {
17309                             if (!isCheckinRequest) {
17310                                 pw.println("Got RemoteException! " + e);
17311                                 pw.flush();
17312                             }
17313                         }
17314                     }
17315                 }
17316
17317                 final long myTotalPss = mi.getTotalPss();
17318                 final long myTotalUss = mi.getTotalUss();
17319                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17320
17321                 synchronized (this) {
17322                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17323                         // Record this for posterity if the process has been stable.
17324                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17325                     }
17326                 }
17327
17328                 if (!isCheckinRequest && mi != null) {
17329                     totalPss += myTotalPss;
17330                     totalSwapPss += myTotalSwapPss;
17331                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17332                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17333                             myTotalSwapPss, pid, hasActivities);
17334                     procMems.add(pssItem);
17335                     procMemsMap.put(pid, pssItem);
17336
17337                     nativePss += mi.nativePss;
17338                     nativeSwapPss += mi.nativeSwappedOutPss;
17339                     dalvikPss += mi.dalvikPss;
17340                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17341                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17342                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17343                         dalvikSubitemSwapPss[j] +=
17344                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17345                     }
17346                     otherPss += mi.otherPss;
17347                     otherSwapPss += mi.otherSwappedOutPss;
17348                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17349                         long mem = mi.getOtherPss(j);
17350                         miscPss[j] += mem;
17351                         otherPss -= mem;
17352                         mem = mi.getOtherSwappedOutPss(j);
17353                         miscSwapPss[j] += mem;
17354                         otherSwapPss -= mem;
17355                     }
17356
17357                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17358                         cachedPss += myTotalPss;
17359                         cachedSwapPss += myTotalSwapPss;
17360                     }
17361
17362                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17363                         if (oomIndex == (oomPss.length - 1)
17364                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17365                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17366                             oomPss[oomIndex] += myTotalPss;
17367                             oomSwapPss[oomIndex] += myTotalSwapPss;
17368                             if (oomProcs[oomIndex] == null) {
17369                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17370                             }
17371                             oomProcs[oomIndex].add(pssItem);
17372                             break;
17373                         }
17374                     }
17375                 }
17376             }
17377         }
17378
17379         long nativeProcTotalPss = 0;
17380
17381         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17382             // If we are showing aggregations, also look for native processes to
17383             // include so that our aggregations are more accurate.
17384             updateCpuStatsNow();
17385             mi = null;
17386             synchronized (mProcessCpuTracker) {
17387                 final int N = mProcessCpuTracker.countStats();
17388                 for (int i=0; i<N; i++) {
17389                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17390                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17391                         if (mi == null) {
17392                             mi = new Debug.MemoryInfo();
17393                         }
17394                         if (!brief && !oomOnly) {
17395                             Debug.getMemoryInfo(st.pid, mi);
17396                         } else {
17397                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17398                             mi.nativePrivateDirty = (int)tmpLong[0];
17399                         }
17400
17401                         final long myTotalPss = mi.getTotalPss();
17402                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17403                         totalPss += myTotalPss;
17404                         nativeProcTotalPss += myTotalPss;
17405
17406                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17407                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17408                         procMems.add(pssItem);
17409
17410                         nativePss += mi.nativePss;
17411                         nativeSwapPss += mi.nativeSwappedOutPss;
17412                         dalvikPss += mi.dalvikPss;
17413                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17414                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17415                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17416                             dalvikSubitemSwapPss[j] +=
17417                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17418                         }
17419                         otherPss += mi.otherPss;
17420                         otherSwapPss += mi.otherSwappedOutPss;
17421                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17422                             long mem = mi.getOtherPss(j);
17423                             miscPss[j] += mem;
17424                             otherPss -= mem;
17425                             mem = mi.getOtherSwappedOutPss(j);
17426                             miscSwapPss[j] += mem;
17427                             otherSwapPss -= mem;
17428                         }
17429                         oomPss[0] += myTotalPss;
17430                         oomSwapPss[0] += myTotalSwapPss;
17431                         if (oomProcs[0] == null) {
17432                             oomProcs[0] = new ArrayList<MemItem>();
17433                         }
17434                         oomProcs[0].add(pssItem);
17435                     }
17436                 }
17437             }
17438
17439             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17440
17441             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17442             final int dalvikId = -2;
17443             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17444             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17445             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17446                 String label = Debug.MemoryInfo.getOtherLabel(j);
17447                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17448             }
17449             if (dalvikSubitemPss.length > 0) {
17450                 // Add dalvik subitems.
17451                 for (MemItem memItem : catMems) {
17452                     int memItemStart = 0, memItemEnd = 0;
17453                     if (memItem.id == dalvikId) {
17454                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17455                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17456                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17457                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17458                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17459                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17460                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17461                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17462                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17463                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17464                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17465                     } else {
17466                         continue;  // No subitems, continue.
17467                     }
17468                     memItem.subitems = new ArrayList<MemItem>();
17469                     for (int j=memItemStart; j<=memItemEnd; j++) {
17470                         final String name = Debug.MemoryInfo.getOtherLabel(
17471                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17472                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17473                                 dalvikSubitemSwapPss[j], j));
17474                     }
17475                 }
17476             }
17477
17478             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17479             for (int j=0; j<oomPss.length; j++) {
17480                 if (oomPss[j] != 0) {
17481                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17482                             : DUMP_MEM_OOM_LABEL[j];
17483                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17484                             DUMP_MEM_OOM_ADJ[j]);
17485                     item.subitems = oomProcs[j];
17486                     oomMems.add(item);
17487                 }
17488             }
17489
17490             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17491             if (!brief && !oomOnly && !isCompact) {
17492                 pw.println();
17493                 pw.println("Total PSS by process:");
17494                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17495                 pw.println();
17496             }
17497             if (!isCompact) {
17498                 pw.println("Total PSS by OOM adjustment:");
17499             }
17500             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17501             if (!brief && !oomOnly) {
17502                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17503                 if (!isCompact) {
17504                     out.println();
17505                     out.println("Total PSS by category:");
17506                 }
17507                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17508             }
17509             if (!isCompact) {
17510                 pw.println();
17511             }
17512             MemInfoReader memInfo = new MemInfoReader();
17513             memInfo.readMemInfo();
17514             if (nativeProcTotalPss > 0) {
17515                 synchronized (this) {
17516                     final long cachedKb = memInfo.getCachedSizeKb();
17517                     final long freeKb = memInfo.getFreeSizeKb();
17518                     final long zramKb = memInfo.getZramTotalSizeKb();
17519                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17520                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17521                             kernelKb*1024, nativeProcTotalPss*1024);
17522                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17523                             nativeProcTotalPss);
17524                 }
17525             }
17526             if (!brief) {
17527                 if (!isCompact) {
17528                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17529                     pw.print(" (status ");
17530                     switch (mLastMemoryLevel) {
17531                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17532                             pw.println("normal)");
17533                             break;
17534                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17535                             pw.println("moderate)");
17536                             break;
17537                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17538                             pw.println("low)");
17539                             break;
17540                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17541                             pw.println("critical)");
17542                             break;
17543                         default:
17544                             pw.print(mLastMemoryLevel);
17545                             pw.println(")");
17546                             break;
17547                     }
17548                     pw.print(" Free RAM: ");
17549                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17550                             + memInfo.getFreeSizeKb()));
17551                     pw.print(" (");
17552                     pw.print(stringifyKBSize(cachedPss));
17553                     pw.print(" cached pss + ");
17554                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17555                     pw.print(" cached kernel + ");
17556                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17557                     pw.println(" free)");
17558                 } else {
17559                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17560                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17561                             + memInfo.getFreeSizeKb()); pw.print(",");
17562                     pw.println(totalPss - cachedPss);
17563                 }
17564             }
17565             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17566                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17567                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17568             if (!isCompact) {
17569                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17570                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17571                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17572                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17573                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17574             } else {
17575                 pw.print("lostram,"); pw.println(lostRAM);
17576             }
17577             if (!brief) {
17578                 if (memInfo.getZramTotalSizeKb() != 0) {
17579                     if (!isCompact) {
17580                         pw.print("     ZRAM: ");
17581                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17582                                 pw.print(" physical used for ");
17583                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17584                                         - memInfo.getSwapFreeSizeKb()));
17585                                 pw.print(" in swap (");
17586                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17587                                 pw.println(" total swap)");
17588                     } else {
17589                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17590                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17591                                 pw.println(memInfo.getSwapFreeSizeKb());
17592                     }
17593                 }
17594                 final long[] ksm = getKsmInfo();
17595                 if (!isCompact) {
17596                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17597                             || ksm[KSM_VOLATILE] != 0) {
17598                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17599                                 pw.print(" saved from shared ");
17600                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17601                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17602                                 pw.print(" unshared; ");
17603                                 pw.print(stringifyKBSize(
17604                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17605                     }
17606                     pw.print("   Tuning: ");
17607                     pw.print(ActivityManager.staticGetMemoryClass());
17608                     pw.print(" (large ");
17609                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17610                     pw.print("), oom ");
17611                     pw.print(stringifySize(
17612                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17613                     pw.print(", restore limit ");
17614                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17615                     if (ActivityManager.isLowRamDeviceStatic()) {
17616                         pw.print(" (low-ram)");
17617                     }
17618                     if (ActivityManager.isHighEndGfx()) {
17619                         pw.print(" (high-end-gfx)");
17620                     }
17621                     pw.println();
17622                 } else {
17623                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17624                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17625                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17626                     pw.print("tuning,");
17627                     pw.print(ActivityManager.staticGetMemoryClass());
17628                     pw.print(',');
17629                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17630                     pw.print(',');
17631                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17632                     if (ActivityManager.isLowRamDeviceStatic()) {
17633                         pw.print(",low-ram");
17634                     }
17635                     if (ActivityManager.isHighEndGfx()) {
17636                         pw.print(",high-end-gfx");
17637                     }
17638                     pw.println();
17639                 }
17640             }
17641         }
17642     }
17643
17644     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17645             long memtrack, String name) {
17646         sb.append("  ");
17647         sb.append(ProcessList.makeOomAdjString(oomAdj));
17648         sb.append(' ');
17649         sb.append(ProcessList.makeProcStateString(procState));
17650         sb.append(' ');
17651         ProcessList.appendRamKb(sb, pss);
17652         sb.append(": ");
17653         sb.append(name);
17654         if (memtrack > 0) {
17655             sb.append(" (");
17656             sb.append(stringifyKBSize(memtrack));
17657             sb.append(" memtrack)");
17658         }
17659     }
17660
17661     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17662         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17663         sb.append(" (pid ");
17664         sb.append(mi.pid);
17665         sb.append(") ");
17666         sb.append(mi.adjType);
17667         sb.append('\n');
17668         if (mi.adjReason != null) {
17669             sb.append("                      ");
17670             sb.append(mi.adjReason);
17671             sb.append('\n');
17672         }
17673     }
17674
17675     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17676         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17677         for (int i=0, N=memInfos.size(); i<N; i++) {
17678             ProcessMemInfo mi = memInfos.get(i);
17679             infoMap.put(mi.pid, mi);
17680         }
17681         updateCpuStatsNow();
17682         long[] memtrackTmp = new long[1];
17683         final List<ProcessCpuTracker.Stats> stats;
17684         // Get a list of Stats that have vsize > 0
17685         synchronized (mProcessCpuTracker) {
17686             stats = mProcessCpuTracker.getStats((st) -> {
17687                 return st.vsize > 0;
17688             });
17689         }
17690         final int statsCount = stats.size();
17691         for (int i = 0; i < statsCount; i++) {
17692             ProcessCpuTracker.Stats st = stats.get(i);
17693             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17694             if (pss > 0) {
17695                 if (infoMap.indexOfKey(st.pid) < 0) {
17696                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17697                             ProcessList.NATIVE_ADJ, -1, "native", null);
17698                     mi.pss = pss;
17699                     mi.memtrack = memtrackTmp[0];
17700                     memInfos.add(mi);
17701                 }
17702             }
17703         }
17704
17705         long totalPss = 0;
17706         long totalMemtrack = 0;
17707         for (int i=0, N=memInfos.size(); i<N; i++) {
17708             ProcessMemInfo mi = memInfos.get(i);
17709             if (mi.pss == 0) {
17710                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17711                 mi.memtrack = memtrackTmp[0];
17712             }
17713             totalPss += mi.pss;
17714             totalMemtrack += mi.memtrack;
17715         }
17716         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17717             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17718                 if (lhs.oomAdj != rhs.oomAdj) {
17719                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17720                 }
17721                 if (lhs.pss != rhs.pss) {
17722                     return lhs.pss < rhs.pss ? 1 : -1;
17723                 }
17724                 return 0;
17725             }
17726         });
17727
17728         StringBuilder tag = new StringBuilder(128);
17729         StringBuilder stack = new StringBuilder(128);
17730         tag.append("Low on memory -- ");
17731         appendMemBucket(tag, totalPss, "total", false);
17732         appendMemBucket(stack, totalPss, "total", true);
17733
17734         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17735         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17736         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17737
17738         boolean firstLine = true;
17739         int lastOomAdj = Integer.MIN_VALUE;
17740         long extraNativeRam = 0;
17741         long extraNativeMemtrack = 0;
17742         long cachedPss = 0;
17743         for (int i=0, N=memInfos.size(); i<N; i++) {
17744             ProcessMemInfo mi = memInfos.get(i);
17745
17746             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17747                 cachedPss += mi.pss;
17748             }
17749
17750             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17751                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17752                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17753                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17754                 if (lastOomAdj != mi.oomAdj) {
17755                     lastOomAdj = mi.oomAdj;
17756                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17757                         tag.append(" / ");
17758                     }
17759                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17760                         if (firstLine) {
17761                             stack.append(":");
17762                             firstLine = false;
17763                         }
17764                         stack.append("\n\t at ");
17765                     } else {
17766                         stack.append("$");
17767                     }
17768                 } else {
17769                     tag.append(" ");
17770                     stack.append("$");
17771                 }
17772                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17773                     appendMemBucket(tag, mi.pss, mi.name, false);
17774                 }
17775                 appendMemBucket(stack, mi.pss, mi.name, true);
17776                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17777                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17778                     stack.append("(");
17779                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17780                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17781                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17782                             stack.append(":");
17783                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17784                         }
17785                     }
17786                     stack.append(")");
17787                 }
17788             }
17789
17790             appendMemInfo(fullNativeBuilder, mi);
17791             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17792                 // The short form only has native processes that are >= 512K.
17793                 if (mi.pss >= 512) {
17794                     appendMemInfo(shortNativeBuilder, mi);
17795                 } else {
17796                     extraNativeRam += mi.pss;
17797                     extraNativeMemtrack += mi.memtrack;
17798                 }
17799             } else {
17800                 // Short form has all other details, but if we have collected RAM
17801                 // from smaller native processes let's dump a summary of that.
17802                 if (extraNativeRam > 0) {
17803                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17804                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17805                     shortNativeBuilder.append('\n');
17806                     extraNativeRam = 0;
17807                 }
17808                 appendMemInfo(fullJavaBuilder, mi);
17809             }
17810         }
17811
17812         fullJavaBuilder.append("           ");
17813         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17814         fullJavaBuilder.append(": TOTAL");
17815         if (totalMemtrack > 0) {
17816             fullJavaBuilder.append(" (");
17817             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17818             fullJavaBuilder.append(" memtrack)");
17819         } else {
17820         }
17821         fullJavaBuilder.append("\n");
17822
17823         MemInfoReader memInfo = new MemInfoReader();
17824         memInfo.readMemInfo();
17825         final long[] infos = memInfo.getRawInfo();
17826
17827         StringBuilder memInfoBuilder = new StringBuilder(1024);
17828         Debug.getMemInfo(infos);
17829         memInfoBuilder.append("  MemInfo: ");
17830         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17831         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17832         memInfoBuilder.append(stringifyKBSize(
17833                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17834         memInfoBuilder.append(stringifyKBSize(
17835                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17836         memInfoBuilder.append(stringifyKBSize(
17837                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17838         memInfoBuilder.append("           ");
17839         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17840         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17841         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17842         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17843         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17844             memInfoBuilder.append("  ZRAM: ");
17845             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17846             memInfoBuilder.append(" RAM, ");
17847             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17848             memInfoBuilder.append(" swap total, ");
17849             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17850             memInfoBuilder.append(" swap free\n");
17851         }
17852         final long[] ksm = getKsmInfo();
17853         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17854                 || ksm[KSM_VOLATILE] != 0) {
17855             memInfoBuilder.append("  KSM: ");
17856             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17857             memInfoBuilder.append(" saved from shared ");
17858             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17859             memInfoBuilder.append("\n       ");
17860             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17861             memInfoBuilder.append(" unshared; ");
17862             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17863             memInfoBuilder.append(" volatile\n");
17864         }
17865         memInfoBuilder.append("  Free RAM: ");
17866         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17867                 + memInfo.getFreeSizeKb()));
17868         memInfoBuilder.append("\n");
17869         memInfoBuilder.append("  Used RAM: ");
17870         memInfoBuilder.append(stringifyKBSize(
17871                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17872         memInfoBuilder.append("\n");
17873         memInfoBuilder.append("  Lost RAM: ");
17874         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17875                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17876                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17877         memInfoBuilder.append("\n");
17878         Slog.i(TAG, "Low on memory:");
17879         Slog.i(TAG, shortNativeBuilder.toString());
17880         Slog.i(TAG, fullJavaBuilder.toString());
17881         Slog.i(TAG, memInfoBuilder.toString());
17882
17883         StringBuilder dropBuilder = new StringBuilder(1024);
17884         /*
17885         StringWriter oomSw = new StringWriter();
17886         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17887         StringWriter catSw = new StringWriter();
17888         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17889         String[] emptyArgs = new String[] { };
17890         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17891         oomPw.flush();
17892         String oomString = oomSw.toString();
17893         */
17894         dropBuilder.append("Low on memory:");
17895         dropBuilder.append(stack);
17896         dropBuilder.append('\n');
17897         dropBuilder.append(fullNativeBuilder);
17898         dropBuilder.append(fullJavaBuilder);
17899         dropBuilder.append('\n');
17900         dropBuilder.append(memInfoBuilder);
17901         dropBuilder.append('\n');
17902         /*
17903         dropBuilder.append(oomString);
17904         dropBuilder.append('\n');
17905         */
17906         StringWriter catSw = new StringWriter();
17907         synchronized (ActivityManagerService.this) {
17908             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17909             String[] emptyArgs = new String[] { };
17910             catPw.println();
17911             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17912             catPw.println();
17913             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17914                     false, null).dumpLocked();
17915             catPw.println();
17916             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17917             catPw.flush();
17918         }
17919         dropBuilder.append(catSw.toString());
17920         addErrorToDropBox("lowmem", null, "system_server", null,
17921                 null, tag.toString(), dropBuilder.toString(), null, null);
17922         //Slog.i(TAG, "Sent to dropbox:");
17923         //Slog.i(TAG, dropBuilder.toString());
17924         synchronized (ActivityManagerService.this) {
17925             long now = SystemClock.uptimeMillis();
17926             if (mLastMemUsageReportTime < now) {
17927                 mLastMemUsageReportTime = now;
17928             }
17929         }
17930     }
17931
17932     /**
17933      * Searches array of arguments for the specified string
17934      * @param args array of argument strings
17935      * @param value value to search for
17936      * @return true if the value is contained in the array
17937      */
17938     private static boolean scanArgs(String[] args, String value) {
17939         if (args != null) {
17940             for (String arg : args) {
17941                 if (value.equals(arg)) {
17942                     return true;
17943                 }
17944             }
17945         }
17946         return false;
17947     }
17948
17949     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17950             ContentProviderRecord cpr, boolean always) {
17951         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17952
17953         if (!inLaunching || always) {
17954             synchronized (cpr) {
17955                 cpr.launchingApp = null;
17956                 cpr.notifyAll();
17957             }
17958             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17959             String names[] = cpr.info.authority.split(";");
17960             for (int j = 0; j < names.length; j++) {
17961                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17962             }
17963         }
17964
17965         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17966             ContentProviderConnection conn = cpr.connections.get(i);
17967             if (conn.waiting) {
17968                 // If this connection is waiting for the provider, then we don't
17969                 // need to mess with its process unless we are always removing
17970                 // or for some reason the provider is not currently launching.
17971                 if (inLaunching && !always) {
17972                     continue;
17973                 }
17974             }
17975             ProcessRecord capp = conn.client;
17976             conn.dead = true;
17977             if (conn.stableCount > 0) {
17978                 if (!capp.persistent && capp.thread != null
17979                         && capp.pid != 0
17980                         && capp.pid != MY_PID) {
17981                     capp.kill("depends on provider "
17982                             + cpr.name.flattenToShortString()
17983                             + " in dying proc " + (proc != null ? proc.processName : "??")
17984                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17985                 }
17986             } else if (capp.thread != null && conn.provider.provider != null) {
17987                 try {
17988                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17989                 } catch (RemoteException e) {
17990                 }
17991                 // In the protocol here, we don't expect the client to correctly
17992                 // clean up this connection, we'll just remove it.
17993                 cpr.connections.remove(i);
17994                 if (conn.client.conProviders.remove(conn)) {
17995                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
17996                 }
17997             }
17998         }
17999
18000         if (inLaunching && always) {
18001             mLaunchingProviders.remove(cpr);
18002         }
18003         return inLaunching;
18004     }
18005
18006     /**
18007      * Main code for cleaning up a process when it has gone away.  This is
18008      * called both as a result of the process dying, or directly when stopping
18009      * a process when running in single process mode.
18010      *
18011      * @return Returns true if the given process has been restarted, so the
18012      * app that was passed in must remain on the process lists.
18013      */
18014     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18015             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18016         if (index >= 0) {
18017             removeLruProcessLocked(app);
18018             ProcessList.remove(app.pid);
18019         }
18020
18021         mProcessesToGc.remove(app);
18022         mPendingPssProcesses.remove(app);
18023
18024         // Dismiss any open dialogs.
18025         if (app.crashDialog != null && !app.forceCrashReport) {
18026             app.crashDialog.dismiss();
18027             app.crashDialog = null;
18028         }
18029         if (app.anrDialog != null) {
18030             app.anrDialog.dismiss();
18031             app.anrDialog = null;
18032         }
18033         if (app.waitDialog != null) {
18034             app.waitDialog.dismiss();
18035             app.waitDialog = null;
18036         }
18037
18038         app.crashing = false;
18039         app.notResponding = false;
18040
18041         app.resetPackageList(mProcessStats);
18042         app.unlinkDeathRecipient();
18043         app.makeInactive(mProcessStats);
18044         app.waitingToKill = null;
18045         app.forcingToImportant = null;
18046         updateProcessForegroundLocked(app, false, false);
18047         app.foregroundActivities = false;
18048         app.hasShownUi = false;
18049         app.treatLikeActivity = false;
18050         app.hasAboveClient = false;
18051         app.hasClientActivities = false;
18052
18053         mServices.killServicesLocked(app, allowRestart);
18054
18055         boolean restart = false;
18056
18057         // Remove published content providers.
18058         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18059             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18060             final boolean always = app.bad || !allowRestart;
18061             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18062             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18063                 // We left the provider in the launching list, need to
18064                 // restart it.
18065                 restart = true;
18066             }
18067
18068             cpr.provider = null;
18069             cpr.proc = null;
18070         }
18071         app.pubProviders.clear();
18072
18073         // Take care of any launching providers waiting for this process.
18074         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18075             restart = true;
18076         }
18077
18078         // Unregister from connected content providers.
18079         if (!app.conProviders.isEmpty()) {
18080             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18081                 ContentProviderConnection conn = app.conProviders.get(i);
18082                 conn.provider.connections.remove(conn);
18083                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18084                         conn.provider.name);
18085             }
18086             app.conProviders.clear();
18087         }
18088
18089         // At this point there may be remaining entries in mLaunchingProviders
18090         // where we were the only one waiting, so they are no longer of use.
18091         // Look for these and clean up if found.
18092         // XXX Commented out for now.  Trying to figure out a way to reproduce
18093         // the actual situation to identify what is actually going on.
18094         if (false) {
18095             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18096                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18097                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18098                     synchronized (cpr) {
18099                         cpr.launchingApp = null;
18100                         cpr.notifyAll();
18101                     }
18102                 }
18103             }
18104         }
18105
18106         skipCurrentReceiverLocked(app);
18107
18108         // Unregister any receivers.
18109         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18110             removeReceiverLocked(app.receivers.valueAt(i));
18111         }
18112         app.receivers.clear();
18113
18114         // If the app is undergoing backup, tell the backup manager about it
18115         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18116             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18117                     + mBackupTarget.appInfo + " died during backup");
18118             mHandler.post(new Runnable() {
18119                 @Override
18120                 public void run(){
18121                     try {
18122                         IBackupManager bm = IBackupManager.Stub.asInterface(
18123                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18124                         bm.agentDisconnected(app.info.packageName);
18125                     } catch (RemoteException e) {
18126                         // can't happen; backup manager is local
18127                     }
18128                 }
18129             });
18130         }
18131
18132         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18133             ProcessChangeItem item = mPendingProcessChanges.get(i);
18134             if (item.pid == app.pid) {
18135                 mPendingProcessChanges.remove(i);
18136                 mAvailProcessChanges.add(item);
18137             }
18138         }
18139         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18140                 null).sendToTarget();
18141
18142         // If the caller is restarting this app, then leave it in its
18143         // current lists and let the caller take care of it.
18144         if (restarting) {
18145             return false;
18146         }
18147
18148         if (!app.persistent || app.isolated) {
18149             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18150                     "Removing non-persistent process during cleanup: " + app);
18151             if (!replacingPid) {
18152                 removeProcessNameLocked(app.processName, app.uid, app);
18153             }
18154             if (mHeavyWeightProcess == app) {
18155                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18156                         mHeavyWeightProcess.userId, 0));
18157                 mHeavyWeightProcess = null;
18158             }
18159         } else if (!app.removed) {
18160             // This app is persistent, so we need to keep its record around.
18161             // If it is not already on the pending app list, add it there
18162             // and start a new process for it.
18163             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18164                 mPersistentStartingProcesses.add(app);
18165                 restart = true;
18166             }
18167         }
18168         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18169                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18170         mProcessesOnHold.remove(app);
18171
18172         if (app == mHomeProcess) {
18173             mHomeProcess = null;
18174         }
18175         if (app == mPreviousProcess) {
18176             mPreviousProcess = null;
18177         }
18178
18179         if (restart && !app.isolated) {
18180             // We have components that still need to be running in the
18181             // process, so re-launch it.
18182             if (index < 0) {
18183                 ProcessList.remove(app.pid);
18184             }
18185             addProcessNameLocked(app);
18186             startProcessLocked(app, "restart", app.processName);
18187             return true;
18188         } else if (app.pid > 0 && app.pid != MY_PID) {
18189             // Goodbye!
18190             boolean removed;
18191             synchronized (mPidsSelfLocked) {
18192                 mPidsSelfLocked.remove(app.pid);
18193                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18194             }
18195             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18196             if (app.isolated) {
18197                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18198             }
18199             app.setPid(0);
18200         }
18201         return false;
18202     }
18203
18204     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18205         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18206             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18207             if (cpr.launchingApp == app) {
18208                 return true;
18209             }
18210         }
18211         return false;
18212     }
18213
18214     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18215         // Look through the content providers we are waiting to have launched,
18216         // and if any run in this process then either schedule a restart of
18217         // the process or kill the client waiting for it if this process has
18218         // gone bad.
18219         boolean restart = false;
18220         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18221             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18222             if (cpr.launchingApp == app) {
18223                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18224                     restart = true;
18225                 } else {
18226                     removeDyingProviderLocked(app, cpr, true);
18227                 }
18228             }
18229         }
18230         return restart;
18231     }
18232
18233     // =========================================================
18234     // SERVICES
18235     // =========================================================
18236
18237     @Override
18238     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18239             int flags) {
18240         enforceNotIsolatedCaller("getServices");
18241
18242         final int callingUid = Binder.getCallingUid();
18243         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18244             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18245         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18246             callingUid);
18247         synchronized (this) {
18248             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18249                 allowed, canInteractAcrossUsers);
18250         }
18251     }
18252
18253     @Override
18254     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18255         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18256         synchronized (this) {
18257             return mServices.getRunningServiceControlPanelLocked(name);
18258         }
18259     }
18260
18261     @Override
18262     public ComponentName startService(IApplicationThread caller, Intent service,
18263             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18264             throws TransactionTooLargeException {
18265         enforceNotIsolatedCaller("startService");
18266         // Refuse possible leaked file descriptors
18267         if (service != null && service.hasFileDescriptors() == true) {
18268             throw new IllegalArgumentException("File descriptors passed in Intent");
18269         }
18270
18271         if (callingPackage == null) {
18272             throw new IllegalArgumentException("callingPackage cannot be null");
18273         }
18274
18275         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18276                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18277         synchronized(this) {
18278             final int callingPid = Binder.getCallingPid();
18279             final int callingUid = Binder.getCallingUid();
18280             final long origId = Binder.clearCallingIdentity();
18281             ComponentName res;
18282             try {
18283                 res = mServices.startServiceLocked(caller, service,
18284                         resolvedType, callingPid, callingUid,
18285                         requireForeground, callingPackage, userId);
18286             } finally {
18287                 Binder.restoreCallingIdentity(origId);
18288             }
18289             return res;
18290         }
18291     }
18292
18293     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18294             boolean fgRequired, String callingPackage, int userId)
18295             throws TransactionTooLargeException {
18296         synchronized(this) {
18297             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18298                     "startServiceInPackage: " + service + " type=" + resolvedType);
18299             final long origId = Binder.clearCallingIdentity();
18300             ComponentName res;
18301             try {
18302                 res = mServices.startServiceLocked(null, service,
18303                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18304             } finally {
18305                 Binder.restoreCallingIdentity(origId);
18306             }
18307             return res;
18308         }
18309     }
18310
18311     @Override
18312     public int stopService(IApplicationThread caller, Intent service,
18313             String resolvedType, int userId) {
18314         enforceNotIsolatedCaller("stopService");
18315         // Refuse possible leaked file descriptors
18316         if (service != null && service.hasFileDescriptors() == true) {
18317             throw new IllegalArgumentException("File descriptors passed in Intent");
18318         }
18319
18320         synchronized(this) {
18321             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18322         }
18323     }
18324
18325     @Override
18326     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18327         enforceNotIsolatedCaller("peekService");
18328         // Refuse possible leaked file descriptors
18329         if (service != null && service.hasFileDescriptors() == true) {
18330             throw new IllegalArgumentException("File descriptors passed in Intent");
18331         }
18332
18333         if (callingPackage == null) {
18334             throw new IllegalArgumentException("callingPackage cannot be null");
18335         }
18336
18337         synchronized(this) {
18338             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18339         }
18340     }
18341
18342     @Override
18343     public boolean stopServiceToken(ComponentName className, IBinder token,
18344             int startId) {
18345         synchronized(this) {
18346             return mServices.stopServiceTokenLocked(className, token, startId);
18347         }
18348     }
18349
18350     @Override
18351     public void setServiceForeground(ComponentName className, IBinder token,
18352             int id, Notification notification, int flags) {
18353         synchronized(this) {
18354             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18355         }
18356     }
18357
18358     @Override
18359     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18360             boolean requireFull, String name, String callerPackage) {
18361         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18362                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18363     }
18364
18365     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18366             String className, int flags) {
18367         boolean result = false;
18368         // For apps that don't have pre-defined UIDs, check for permission
18369         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18370             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18371                 if (ActivityManager.checkUidPermission(
18372                         INTERACT_ACROSS_USERS,
18373                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18374                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18375                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18376                             + " requests FLAG_SINGLE_USER, but app does not hold "
18377                             + INTERACT_ACROSS_USERS;
18378                     Slog.w(TAG, msg);
18379                     throw new SecurityException(msg);
18380                 }
18381                 // Permission passed
18382                 result = true;
18383             }
18384         } else if ("system".equals(componentProcessName)) {
18385             result = true;
18386         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18387             // Phone app and persistent apps are allowed to export singleuser providers.
18388             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18389                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18390         }
18391         if (DEBUG_MU) Slog.v(TAG_MU,
18392                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18393                 + Integer.toHexString(flags) + ") = " + result);
18394         return result;
18395     }
18396
18397     /**
18398      * Checks to see if the caller is in the same app as the singleton
18399      * component, or the component is in a special app. It allows special apps
18400      * to export singleton components but prevents exporting singleton
18401      * components for regular apps.
18402      */
18403     boolean isValidSingletonCall(int callingUid, int componentUid) {
18404         int componentAppId = UserHandle.getAppId(componentUid);
18405         return UserHandle.isSameApp(callingUid, componentUid)
18406                 || componentAppId == SYSTEM_UID
18407                 || componentAppId == PHONE_UID
18408                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18409                         == PackageManager.PERMISSION_GRANTED;
18410     }
18411
18412     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18413             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18414             int userId) throws TransactionTooLargeException {
18415         enforceNotIsolatedCaller("bindService");
18416
18417         // Refuse possible leaked file descriptors
18418         if (service != null && service.hasFileDescriptors() == true) {
18419             throw new IllegalArgumentException("File descriptors passed in Intent");
18420         }
18421
18422         if (callingPackage == null) {
18423             throw new IllegalArgumentException("callingPackage cannot be null");
18424         }
18425
18426         synchronized(this) {
18427             return mServices.bindServiceLocked(caller, token, service,
18428                     resolvedType, connection, flags, callingPackage, userId);
18429         }
18430     }
18431
18432     public boolean unbindService(IServiceConnection connection) {
18433         synchronized (this) {
18434             return mServices.unbindServiceLocked(connection);
18435         }
18436     }
18437
18438     public void publishService(IBinder token, Intent intent, IBinder service) {
18439         // Refuse possible leaked file descriptors
18440         if (intent != null && intent.hasFileDescriptors() == true) {
18441             throw new IllegalArgumentException("File descriptors passed in Intent");
18442         }
18443
18444         synchronized(this) {
18445             if (!(token instanceof ServiceRecord)) {
18446                 throw new IllegalArgumentException("Invalid service token");
18447             }
18448             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18449         }
18450     }
18451
18452     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18453         // Refuse possible leaked file descriptors
18454         if (intent != null && intent.hasFileDescriptors() == true) {
18455             throw new IllegalArgumentException("File descriptors passed in Intent");
18456         }
18457
18458         synchronized(this) {
18459             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18460         }
18461     }
18462
18463     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18464         synchronized(this) {
18465             if (!(token instanceof ServiceRecord)) {
18466                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18467                 throw new IllegalArgumentException("Invalid service token");
18468             }
18469             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18470         }
18471     }
18472
18473     // =========================================================
18474     // BACKUP AND RESTORE
18475     // =========================================================
18476
18477     // Cause the target app to be launched if necessary and its backup agent
18478     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18479     // activity manager to announce its creation.
18480     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18481         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18482         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18483
18484         IPackageManager pm = AppGlobals.getPackageManager();
18485         ApplicationInfo app = null;
18486         try {
18487             app = pm.getApplicationInfo(packageName, 0, userId);
18488         } catch (RemoteException e) {
18489             // can't happen; package manager is process-local
18490         }
18491         if (app == null) {
18492             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18493             return false;
18494         }
18495
18496         int oldBackupUid;
18497         int newBackupUid;
18498
18499         synchronized(this) {
18500             // !!! TODO: currently no check here that we're already bound
18501             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18502             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18503             synchronized (stats) {
18504                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18505             }
18506
18507             // Backup agent is now in use, its package can't be stopped.
18508             try {
18509                 AppGlobals.getPackageManager().setPackageStoppedState(
18510                         app.packageName, false, UserHandle.getUserId(app.uid));
18511             } catch (RemoteException e) {
18512             } catch (IllegalArgumentException e) {
18513                 Slog.w(TAG, "Failed trying to unstop package "
18514                         + app.packageName + ": " + e);
18515             }
18516
18517             BackupRecord r = new BackupRecord(ss, app, backupMode);
18518             ComponentName hostingName =
18519                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18520                             ? new ComponentName(app.packageName, app.backupAgentName)
18521                             : new ComponentName("android", "FullBackupAgent");
18522             // startProcessLocked() returns existing proc's record if it's already running
18523             ProcessRecord proc = startProcessLocked(app.processName, app,
18524                     false, 0, "backup", hostingName, false, false, false);
18525             if (proc == null) {
18526                 Slog.e(TAG, "Unable to start backup agent process " + r);
18527                 return false;
18528             }
18529
18530             // If the app is a regular app (uid >= 10000) and not the system server or phone
18531             // process, etc, then mark it as being in full backup so that certain calls to the
18532             // process can be blocked. This is not reset to false anywhere because we kill the
18533             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18534             if (UserHandle.isApp(app.uid) &&
18535                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18536                 proc.inFullBackup = true;
18537             }
18538             r.app = proc;
18539             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18540             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18541             mBackupTarget = r;
18542             mBackupAppName = app.packageName;
18543
18544             // Try not to kill the process during backup
18545             updateOomAdjLocked(proc, true);
18546
18547             // If the process is already attached, schedule the creation of the backup agent now.
18548             // If it is not yet live, this will be done when it attaches to the framework.
18549             if (proc.thread != null) {
18550                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18551                 try {
18552                     proc.thread.scheduleCreateBackupAgent(app,
18553                             compatibilityInfoForPackageLocked(app), backupMode);
18554                 } catch (RemoteException e) {
18555                     // Will time out on the backup manager side
18556                 }
18557             } else {
18558                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18559             }
18560             // Invariants: at this point, the target app process exists and the application
18561             // is either already running or in the process of coming up.  mBackupTarget and
18562             // mBackupAppName describe the app, so that when it binds back to the AM we
18563             // know that it's scheduled for a backup-agent operation.
18564         }
18565
18566         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18567         if (oldBackupUid != -1) {
18568             js.removeBackingUpUid(oldBackupUid);
18569         }
18570         if (newBackupUid != -1) {
18571             js.addBackingUpUid(newBackupUid);
18572         }
18573
18574         return true;
18575     }
18576
18577     @Override
18578     public void clearPendingBackup() {
18579         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18580         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18581
18582         synchronized (this) {
18583             mBackupTarget = null;
18584             mBackupAppName = null;
18585         }
18586
18587         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18588         js.clearAllBackingUpUids();
18589     }
18590
18591     // A backup agent has just come up
18592     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18593         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18594                 + " = " + agent);
18595
18596         synchronized(this) {
18597             if (!agentPackageName.equals(mBackupAppName)) {
18598                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18599                 return;
18600             }
18601         }
18602
18603         long oldIdent = Binder.clearCallingIdentity();
18604         try {
18605             IBackupManager bm = IBackupManager.Stub.asInterface(
18606                     ServiceManager.getService(Context.BACKUP_SERVICE));
18607             bm.agentConnected(agentPackageName, agent);
18608         } catch (RemoteException e) {
18609             // can't happen; the backup manager service is local
18610         } catch (Exception e) {
18611             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18612             e.printStackTrace();
18613         } finally {
18614             Binder.restoreCallingIdentity(oldIdent);
18615         }
18616     }
18617
18618     // done with this agent
18619     public void unbindBackupAgent(ApplicationInfo appInfo) {
18620         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18621         if (appInfo == null) {
18622             Slog.w(TAG, "unbind backup agent for null app");
18623             return;
18624         }
18625
18626         int oldBackupUid;
18627
18628         synchronized(this) {
18629             try {
18630                 if (mBackupAppName == null) {
18631                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18632                     return;
18633                 }
18634
18635                 if (!mBackupAppName.equals(appInfo.packageName)) {
18636                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18637                     return;
18638                 }
18639
18640                 // Not backing this app up any more; reset its OOM adjustment
18641                 final ProcessRecord proc = mBackupTarget.app;
18642                 updateOomAdjLocked(proc, true);
18643                 proc.inFullBackup = false;
18644
18645                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18646
18647                 // If the app crashed during backup, 'thread' will be null here
18648                 if (proc.thread != null) {
18649                     try {
18650                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18651                                 compatibilityInfoForPackageLocked(appInfo));
18652                     } catch (Exception e) {
18653                         Slog.e(TAG, "Exception when unbinding backup agent:");
18654                         e.printStackTrace();
18655                     }
18656                 }
18657             } finally {
18658                 mBackupTarget = null;
18659                 mBackupAppName = null;
18660             }
18661         }
18662
18663         if (oldBackupUid != -1) {
18664             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18665             js.removeBackingUpUid(oldBackupUid);
18666         }
18667     }
18668
18669     // =========================================================
18670     // BROADCASTS
18671     // =========================================================
18672
18673     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18674         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18675             return false;
18676         }
18677         // Easy case -- we have the app's ProcessRecord.
18678         if (record != null) {
18679             return record.info.isInstantApp();
18680         }
18681         // Otherwise check with PackageManager.
18682         if (callerPackage == null) {
18683             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18684             throw new IllegalArgumentException("Calling application did not provide package name");
18685         }
18686         mAppOpsService.checkPackage(uid, callerPackage);
18687         try {
18688             IPackageManager pm = AppGlobals.getPackageManager();
18689             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18690         } catch (RemoteException e) {
18691             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18692             return true;
18693         }
18694     }
18695
18696     boolean isPendingBroadcastProcessLocked(int pid) {
18697         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18698                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18699     }
18700
18701     void skipPendingBroadcastLocked(int pid) {
18702             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18703             for (BroadcastQueue queue : mBroadcastQueues) {
18704                 queue.skipPendingBroadcastLocked(pid);
18705             }
18706     }
18707
18708     // The app just attached; send any pending broadcasts that it should receive
18709     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18710         boolean didSomething = false;
18711         for (BroadcastQueue queue : mBroadcastQueues) {
18712             didSomething |= queue.sendPendingBroadcastsLocked(app);
18713         }
18714         return didSomething;
18715     }
18716
18717     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18718             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18719             int flags) {
18720         enforceNotIsolatedCaller("registerReceiver");
18721         ArrayList<Intent> stickyIntents = null;
18722         ProcessRecord callerApp = null;
18723         final boolean visibleToInstantApps
18724                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18725         int callingUid;
18726         int callingPid;
18727         boolean instantApp;
18728         synchronized(this) {
18729             if (caller != null) {
18730                 callerApp = getRecordForAppLocked(caller);
18731                 if (callerApp == null) {
18732                     throw new SecurityException(
18733                             "Unable to find app for caller " + caller
18734                             + " (pid=" + Binder.getCallingPid()
18735                             + ") when registering receiver " + receiver);
18736                 }
18737                 if (callerApp.info.uid != SYSTEM_UID &&
18738                         !callerApp.pkgList.containsKey(callerPackage) &&
18739                         !"android".equals(callerPackage)) {
18740                     throw new SecurityException("Given caller package " + callerPackage
18741                             + " is not running in process " + callerApp);
18742                 }
18743                 callingUid = callerApp.info.uid;
18744                 callingPid = callerApp.pid;
18745             } else {
18746                 callerPackage = null;
18747                 callingUid = Binder.getCallingUid();
18748                 callingPid = Binder.getCallingPid();
18749             }
18750
18751             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18752             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18753                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18754
18755             Iterator<String> actions = filter.actionsIterator();
18756             if (actions == null) {
18757                 ArrayList<String> noAction = new ArrayList<String>(1);
18758                 noAction.add(null);
18759                 actions = noAction.iterator();
18760             }
18761
18762             // Collect stickies of users
18763             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18764             while (actions.hasNext()) {
18765                 String action = actions.next();
18766                 for (int id : userIds) {
18767                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18768                     if (stickies != null) {
18769                         ArrayList<Intent> intents = stickies.get(action);
18770                         if (intents != null) {
18771                             if (stickyIntents == null) {
18772                                 stickyIntents = new ArrayList<Intent>();
18773                             }
18774                             stickyIntents.addAll(intents);
18775                         }
18776                     }
18777                 }
18778             }
18779         }
18780
18781         ArrayList<Intent> allSticky = null;
18782         if (stickyIntents != null) {
18783             final ContentResolver resolver = mContext.getContentResolver();
18784             // Look for any matching sticky broadcasts...
18785             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18786                 Intent intent = stickyIntents.get(i);
18787                 // Don't provided intents that aren't available to instant apps.
18788                 if (instantApp &&
18789                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18790                     continue;
18791                 }
18792                 // If intent has scheme "content", it will need to acccess
18793                 // provider that needs to lock mProviderMap in ActivityThread
18794                 // and also it may need to wait application response, so we
18795                 // cannot lock ActivityManagerService here.
18796                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18797                     if (allSticky == null) {
18798                         allSticky = new ArrayList<Intent>();
18799                     }
18800                     allSticky.add(intent);
18801                 }
18802             }
18803         }
18804
18805         // The first sticky in the list is returned directly back to the client.
18806         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18807         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18808         if (receiver == null) {
18809             return sticky;
18810         }
18811
18812         synchronized (this) {
18813             if (callerApp != null && (callerApp.thread == null
18814                     || callerApp.thread.asBinder() != caller.asBinder())) {
18815                 // Original caller already died
18816                 return null;
18817             }
18818             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18819             if (rl == null) {
18820                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18821                         userId, receiver);
18822                 if (rl.app != null) {
18823                     rl.app.receivers.add(rl);
18824                 } else {
18825                     try {
18826                         receiver.asBinder().linkToDeath(rl, 0);
18827                     } catch (RemoteException e) {
18828                         return sticky;
18829                     }
18830                     rl.linkedToDeath = true;
18831                 }
18832                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18833             } else if (rl.uid != callingUid) {
18834                 throw new IllegalArgumentException(
18835                         "Receiver requested to register for uid " + callingUid
18836                         + " was previously registered for uid " + rl.uid
18837                         + " callerPackage is " + callerPackage);
18838             } else if (rl.pid != callingPid) {
18839                 throw new IllegalArgumentException(
18840                         "Receiver requested to register for pid " + callingPid
18841                         + " was previously registered for pid " + rl.pid
18842                         + " callerPackage is " + callerPackage);
18843             } else if (rl.userId != userId) {
18844                 throw new IllegalArgumentException(
18845                         "Receiver requested to register for user " + userId
18846                         + " was previously registered for user " + rl.userId
18847                         + " callerPackage is " + callerPackage);
18848             }
18849             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18850                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18851             rl.add(bf);
18852             if (!bf.debugCheck()) {
18853                 Slog.w(TAG, "==> For Dynamic broadcast");
18854             }
18855             mReceiverResolver.addFilter(bf);
18856
18857             // Enqueue broadcasts for all existing stickies that match
18858             // this filter.
18859             if (allSticky != null) {
18860                 ArrayList receivers = new ArrayList();
18861                 receivers.add(bf);
18862
18863                 final int stickyCount = allSticky.size();
18864                 for (int i = 0; i < stickyCount; i++) {
18865                     Intent intent = allSticky.get(i);
18866                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18867                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18868                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18869                             null, 0, null, null, false, true, true, -1);
18870                     queue.enqueueParallelBroadcastLocked(r);
18871                     queue.scheduleBroadcastsLocked();
18872                 }
18873             }
18874
18875             return sticky;
18876         }
18877     }
18878
18879     public void unregisterReceiver(IIntentReceiver receiver) {
18880         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18881
18882         final long origId = Binder.clearCallingIdentity();
18883         try {
18884             boolean doTrim = false;
18885
18886             synchronized(this) {
18887                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18888                 if (rl != null) {
18889                     final BroadcastRecord r = rl.curBroadcast;
18890                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18891                         final boolean doNext = r.queue.finishReceiverLocked(
18892                                 r, r.resultCode, r.resultData, r.resultExtras,
18893                                 r.resultAbort, false);
18894                         if (doNext) {
18895                             doTrim = true;
18896                             r.queue.processNextBroadcast(false);
18897                         }
18898                     }
18899
18900                     if (rl.app != null) {
18901                         rl.app.receivers.remove(rl);
18902                     }
18903                     removeReceiverLocked(rl);
18904                     if (rl.linkedToDeath) {
18905                         rl.linkedToDeath = false;
18906                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18907                     }
18908                 }
18909             }
18910
18911             // If we actually concluded any broadcasts, we might now be able
18912             // to trim the recipients' apps from our working set
18913             if (doTrim) {
18914                 trimApplications();
18915                 return;
18916             }
18917
18918         } finally {
18919             Binder.restoreCallingIdentity(origId);
18920         }
18921     }
18922
18923     void removeReceiverLocked(ReceiverList rl) {
18924         mRegisteredReceivers.remove(rl.receiver.asBinder());
18925         for (int i = rl.size() - 1; i >= 0; i--) {
18926             mReceiverResolver.removeFilter(rl.get(i));
18927         }
18928     }
18929
18930     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18931         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18932             ProcessRecord r = mLruProcesses.get(i);
18933             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18934                 try {
18935                     r.thread.dispatchPackageBroadcast(cmd, packages);
18936                 } catch (RemoteException ex) {
18937                 }
18938             }
18939         }
18940     }
18941
18942     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18943             int callingUid, int[] users) {
18944         // TODO: come back and remove this assumption to triage all broadcasts
18945         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18946
18947         List<ResolveInfo> receivers = null;
18948         try {
18949             HashSet<ComponentName> singleUserReceivers = null;
18950             boolean scannedFirstReceivers = false;
18951             for (int user : users) {
18952                 // Skip users that have Shell restrictions, with exception of always permitted
18953                 // Shell broadcasts
18954                 if (callingUid == SHELL_UID
18955                         && mUserController.hasUserRestriction(
18956                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18957                         && !isPermittedShellBroadcast(intent)) {
18958                     continue;
18959                 }
18960                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18961                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18962                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18963                     // If this is not the system user, we need to check for
18964                     // any receivers that should be filtered out.
18965                     for (int i=0; i<newReceivers.size(); i++) {
18966                         ResolveInfo ri = newReceivers.get(i);
18967                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18968                             newReceivers.remove(i);
18969                             i--;
18970                         }
18971                     }
18972                 }
18973                 if (newReceivers != null && newReceivers.size() == 0) {
18974                     newReceivers = null;
18975                 }
18976                 if (receivers == null) {
18977                     receivers = newReceivers;
18978                 } else if (newReceivers != null) {
18979                     // We need to concatenate the additional receivers
18980                     // found with what we have do far.  This would be easy,
18981                     // but we also need to de-dup any receivers that are
18982                     // singleUser.
18983                     if (!scannedFirstReceivers) {
18984                         // Collect any single user receivers we had already retrieved.
18985                         scannedFirstReceivers = true;
18986                         for (int i=0; i<receivers.size(); i++) {
18987                             ResolveInfo ri = receivers.get(i);
18988                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18989                                 ComponentName cn = new ComponentName(
18990                                         ri.activityInfo.packageName, ri.activityInfo.name);
18991                                 if (singleUserReceivers == null) {
18992                                     singleUserReceivers = new HashSet<ComponentName>();
18993                                 }
18994                                 singleUserReceivers.add(cn);
18995                             }
18996                         }
18997                     }
18998                     // Add the new results to the existing results, tracking
18999                     // and de-dupping single user receivers.
19000                     for (int i=0; i<newReceivers.size(); i++) {
19001                         ResolveInfo ri = newReceivers.get(i);
19002                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19003                             ComponentName cn = new ComponentName(
19004                                     ri.activityInfo.packageName, ri.activityInfo.name);
19005                             if (singleUserReceivers == null) {
19006                                 singleUserReceivers = new HashSet<ComponentName>();
19007                             }
19008                             if (!singleUserReceivers.contains(cn)) {
19009                                 singleUserReceivers.add(cn);
19010                                 receivers.add(ri);
19011                             }
19012                         } else {
19013                             receivers.add(ri);
19014                         }
19015                     }
19016                 }
19017             }
19018         } catch (RemoteException ex) {
19019             // pm is in same process, this will never happen.
19020         }
19021         return receivers;
19022     }
19023
19024     private boolean isPermittedShellBroadcast(Intent intent) {
19025         // remote bugreport should always be allowed to be taken
19026         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19027     }
19028
19029     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19030             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19031         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19032             // Don't yell about broadcasts sent via shell
19033             return;
19034         }
19035
19036         final String action = intent.getAction();
19037         if (isProtectedBroadcast
19038                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19039                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19040                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19041                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19042                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19043                 || Intent.ACTION_MASTER_CLEAR.equals(action)
19044                 || Intent.ACTION_FACTORY_RESET.equals(action)
19045                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19046                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19047                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19048                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19049                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19050                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19051                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19052             // Broadcast is either protected, or it's a public action that
19053             // we've relaxed, so it's fine for system internals to send.
19054             return;
19055         }
19056
19057         // This broadcast may be a problem...  but there are often system components that
19058         // want to send an internal broadcast to themselves, which is annoying to have to
19059         // explicitly list each action as a protected broadcast, so we will check for that
19060         // one safe case and allow it: an explicit broadcast, only being received by something
19061         // that has protected itself.
19062         if (receivers != null && receivers.size() > 0
19063                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19064             boolean allProtected = true;
19065             for (int i = receivers.size()-1; i >= 0; i--) {
19066                 Object target = receivers.get(i);
19067                 if (target instanceof ResolveInfo) {
19068                     ResolveInfo ri = (ResolveInfo)target;
19069                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19070                         allProtected = false;
19071                         break;
19072                     }
19073                 } else {
19074                     BroadcastFilter bf = (BroadcastFilter)target;
19075                     if (bf.requiredPermission == null) {
19076                         allProtected = false;
19077                         break;
19078                     }
19079                 }
19080             }
19081             if (allProtected) {
19082                 // All safe!
19083                 return;
19084             }
19085         }
19086
19087         // The vast majority of broadcasts sent from system internals
19088         // should be protected to avoid security holes, so yell loudly
19089         // to ensure we examine these cases.
19090         if (callerApp != null) {
19091             Log.wtf(TAG, "Sending non-protected broadcast " + action
19092                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19093                     new Throwable());
19094         } else {
19095             Log.wtf(TAG, "Sending non-protected broadcast " + action
19096                             + " from system uid " + UserHandle.formatUid(callingUid)
19097                             + " pkg " + callerPackage,
19098                     new Throwable());
19099         }
19100     }
19101
19102     final int broadcastIntentLocked(ProcessRecord callerApp,
19103             String callerPackage, Intent intent, String resolvedType,
19104             IIntentReceiver resultTo, int resultCode, String resultData,
19105             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19106             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19107         intent = new Intent(intent);
19108
19109         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19110         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19111         if (callerInstantApp) {
19112             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19113         }
19114
19115         // By default broadcasts do not go to stopped apps.
19116         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19117
19118         // If we have not finished booting, don't allow this to launch new processes.
19119         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19120             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19121         }
19122
19123         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19124                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19125                 + " ordered=" + ordered + " userid=" + userId);
19126         if ((resultTo != null) && !ordered) {
19127             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19128         }
19129
19130         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19131                 ALLOW_NON_FULL, "broadcast", callerPackage);
19132
19133         // Make sure that the user who is receiving this broadcast is running.
19134         // If not, we will just skip it. Make an exception for shutdown broadcasts
19135         // and upgrade steps.
19136
19137         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19138             if ((callingUid != SYSTEM_UID
19139                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19140                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19141                 Slog.w(TAG, "Skipping broadcast of " + intent
19142                         + ": user " + userId + " is stopped");
19143                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19144             }
19145         }
19146
19147         BroadcastOptions brOptions = null;
19148         if (bOptions != null) {
19149             brOptions = new BroadcastOptions(bOptions);
19150             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19151                 // See if the caller is allowed to do this.  Note we are checking against
19152                 // the actual real caller (not whoever provided the operation as say a
19153                 // PendingIntent), because that who is actually supplied the arguments.
19154                 if (checkComponentPermission(
19155                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19156                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19157                         != PackageManager.PERMISSION_GRANTED) {
19158                     String msg = "Permission Denial: " + intent.getAction()
19159                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19160                             + ", uid=" + callingUid + ")"
19161                             + " requires "
19162                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19163                     Slog.w(TAG, msg);
19164                     throw new SecurityException(msg);
19165                 }
19166             }
19167         }
19168
19169         // Verify that protected broadcasts are only being sent by system code,
19170         // and that system code is only sending protected broadcasts.
19171         final String action = intent.getAction();
19172         final boolean isProtectedBroadcast;
19173         try {
19174             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19175         } catch (RemoteException e) {
19176             Slog.w(TAG, "Remote exception", e);
19177             return ActivityManager.BROADCAST_SUCCESS;
19178         }
19179
19180         final boolean isCallerSystem;
19181         switch (UserHandle.getAppId(callingUid)) {
19182             case ROOT_UID:
19183             case SYSTEM_UID:
19184             case PHONE_UID:
19185             case BLUETOOTH_UID:
19186             case NFC_UID:
19187                 isCallerSystem = true;
19188                 break;
19189             default:
19190                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19191                 break;
19192         }
19193
19194         // First line security check before anything else: stop non-system apps from
19195         // sending protected broadcasts.
19196         if (!isCallerSystem) {
19197             if (isProtectedBroadcast) {
19198                 String msg = "Permission Denial: not allowed to send broadcast "
19199                         + action + " from pid="
19200                         + callingPid + ", uid=" + callingUid;
19201                 Slog.w(TAG, msg);
19202                 throw new SecurityException(msg);
19203
19204             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19205                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19206                 // Special case for compatibility: we don't want apps to send this,
19207                 // but historically it has not been protected and apps may be using it
19208                 // to poke their own app widget.  So, instead of making it protected,
19209                 // just limit it to the caller.
19210                 if (callerPackage == null) {
19211                     String msg = "Permission Denial: not allowed to send broadcast "
19212                             + action + " from unknown caller.";
19213                     Slog.w(TAG, msg);
19214                     throw new SecurityException(msg);
19215                 } else if (intent.getComponent() != null) {
19216                     // They are good enough to send to an explicit component...  verify
19217                     // it is being sent to the calling app.
19218                     if (!intent.getComponent().getPackageName().equals(
19219                             callerPackage)) {
19220                         String msg = "Permission Denial: not allowed to send broadcast "
19221                                 + action + " to "
19222                                 + intent.getComponent().getPackageName() + " from "
19223                                 + callerPackage;
19224                         Slog.w(TAG, msg);
19225                         throw new SecurityException(msg);
19226                     }
19227                 } else {
19228                     // Limit broadcast to their own package.
19229                     intent.setPackage(callerPackage);
19230                 }
19231             }
19232         }
19233
19234         if (action != null) {
19235             if (getBackgroundLaunchBroadcasts().contains(action)) {
19236                 if (DEBUG_BACKGROUND_CHECK) {
19237                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19238                 }
19239                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19240             }
19241
19242             switch (action) {
19243                 case Intent.ACTION_UID_REMOVED:
19244                 case Intent.ACTION_PACKAGE_REMOVED:
19245                 case Intent.ACTION_PACKAGE_CHANGED:
19246                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19247                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19248                 case Intent.ACTION_PACKAGES_SUSPENDED:
19249                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19250                     // Handle special intents: if this broadcast is from the package
19251                     // manager about a package being removed, we need to remove all of
19252                     // its activities from the history stack.
19253                     if (checkComponentPermission(
19254                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19255                             callingPid, callingUid, -1, true)
19256                             != PackageManager.PERMISSION_GRANTED) {
19257                         String msg = "Permission Denial: " + intent.getAction()
19258                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19259                                 + ", uid=" + callingUid + ")"
19260                                 + " requires "
19261                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19262                         Slog.w(TAG, msg);
19263                         throw new SecurityException(msg);
19264                     }
19265                     switch (action) {
19266                         case Intent.ACTION_UID_REMOVED:
19267                             final int uid = getUidFromIntent(intent);
19268                             if (uid >= 0) {
19269                                 mBatteryStatsService.removeUid(uid);
19270                                 mAppOpsService.uidRemoved(uid);
19271                             }
19272                             break;
19273                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19274                             // If resources are unavailable just force stop all those packages
19275                             // and flush the attribute cache as well.
19276                             String list[] =
19277                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19278                             if (list != null && list.length > 0) {
19279                                 for (int i = 0; i < list.length; i++) {
19280                                     forceStopPackageLocked(list[i], -1, false, true, true,
19281                                             false, false, userId, "storage unmount");
19282                                 }
19283                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19284                                 sendPackageBroadcastLocked(
19285                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19286                                         list, userId);
19287                             }
19288                             break;
19289                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19290                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19291                             break;
19292                         case Intent.ACTION_PACKAGE_REMOVED:
19293                         case Intent.ACTION_PACKAGE_CHANGED:
19294                             Uri data = intent.getData();
19295                             String ssp;
19296                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19297                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19298                                 final boolean replacing =
19299                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19300                                 final boolean killProcess =
19301                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19302                                 final boolean fullUninstall = removed && !replacing;
19303                                 if (removed) {
19304                                     if (killProcess) {
19305                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19306                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19307                                                 false, true, true, false, fullUninstall, userId,
19308                                                 removed ? "pkg removed" : "pkg changed");
19309                                     }
19310                                     final int cmd = killProcess
19311                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19312                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19313                                     sendPackageBroadcastLocked(cmd,
19314                                             new String[] {ssp}, userId);
19315                                     if (fullUninstall) {
19316                                         mAppOpsService.packageRemoved(
19317                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19318
19319                                         // Remove all permissions granted from/to this package
19320                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19321
19322                                         removeTasksByPackageNameLocked(ssp, userId);
19323
19324                                         mServices.forceStopPackageLocked(ssp, userId);
19325
19326                                         // Hide the "unsupported display" dialog if necessary.
19327                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19328                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19329                                             mUnsupportedDisplaySizeDialog.dismiss();
19330                                             mUnsupportedDisplaySizeDialog = null;
19331                                         }
19332                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19333                                         mBatteryStatsService.notePackageUninstalled(ssp);
19334                                     }
19335                                 } else {
19336                                     if (killProcess) {
19337                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19338                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19339                                                 userId, ProcessList.INVALID_ADJ,
19340                                                 false, true, true, false, "change " + ssp);
19341                                     }
19342                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19343                                             intent.getStringArrayExtra(
19344                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19345                                 }
19346                             }
19347                             break;
19348                         case Intent.ACTION_PACKAGES_SUSPENDED:
19349                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19350                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19351                                     intent.getAction());
19352                             final String[] packageNames = intent.getStringArrayExtra(
19353                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19354                             final int userHandle = intent.getIntExtra(
19355                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19356
19357                             synchronized(ActivityManagerService.this) {
19358                                 mRecentTasks.onPackagesSuspendedChanged(
19359                                         packageNames, suspended, userHandle);
19360                             }
19361                             break;
19362                     }
19363                     break;
19364                 case Intent.ACTION_PACKAGE_REPLACED:
19365                 {
19366                     final Uri data = intent.getData();
19367                     final String ssp;
19368                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19369                         ApplicationInfo aInfo = null;
19370                         try {
19371                             aInfo = AppGlobals.getPackageManager()
19372                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19373                         } catch (RemoteException ignore) {}
19374                         if (aInfo == null) {
19375                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19376                                     + " ssp=" + ssp + " data=" + data);
19377                             return ActivityManager.BROADCAST_SUCCESS;
19378                         }
19379                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19380                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19381                                 new String[] {ssp}, userId);
19382                     }
19383                     break;
19384                 }
19385                 case Intent.ACTION_PACKAGE_ADDED:
19386                 {
19387                     // Special case for adding a package: by default turn on compatibility mode.
19388                     Uri data = intent.getData();
19389                     String ssp;
19390                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19391                         final boolean replacing =
19392                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19393                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19394
19395                         try {
19396                             ApplicationInfo ai = AppGlobals.getPackageManager().
19397                                     getApplicationInfo(ssp, 0, 0);
19398                             mBatteryStatsService.notePackageInstalled(ssp,
19399                                     ai != null ? ai.versionCode : 0);
19400                         } catch (RemoteException e) {
19401                         }
19402                     }
19403                     break;
19404                 }
19405                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19406                 {
19407                     Uri data = intent.getData();
19408                     String ssp;
19409                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19410                         // Hide the "unsupported display" dialog if necessary.
19411                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19412                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19413                             mUnsupportedDisplaySizeDialog.dismiss();
19414                             mUnsupportedDisplaySizeDialog = null;
19415                         }
19416                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19417                     }
19418                     break;
19419                 }
19420                 case Intent.ACTION_TIMEZONE_CHANGED:
19421                     // If this is the time zone changed action, queue up a message that will reset
19422                     // the timezone of all currently running processes. This message will get
19423                     // queued up before the broadcast happens.
19424                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19425                     break;
19426                 case Intent.ACTION_TIME_CHANGED:
19427                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19428                     // the tri-state value it may contain and "unknown".
19429                     // For convenience we re-use the Intent extra values.
19430                     final int NO_EXTRA_VALUE_FOUND = -1;
19431                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19432                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19433                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19434                     // Only send a message if the time preference is available.
19435                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19436                         Message updateTimePreferenceMsg =
19437                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19438                                         timeFormatPreferenceMsgValue, 0);
19439                         mHandler.sendMessage(updateTimePreferenceMsg);
19440                     }
19441                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19442                     synchronized (stats) {
19443                         stats.noteCurrentTimeChangedLocked();
19444                     }
19445                     break;
19446                 case Intent.ACTION_CLEAR_DNS_CACHE:
19447                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19448                     break;
19449                 case Proxy.PROXY_CHANGE_ACTION:
19450                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19451                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19452                     break;
19453                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19454                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19455                     // In N we just turned these off; in O we are turing them back on partly,
19456                     // only for registered receivers.  This will still address the main problem
19457                     // (a spam of apps waking up when a picture is taken putting significant
19458                     // memory pressure on the system at a bad point), while still allowing apps
19459                     // that are already actively running to know about this happening.
19460                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19461                     break;
19462                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19463                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19464                     break;
19465                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19466                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19467                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19468                     Log.w(TAG, "Broadcast " + action
19469                             + " no longer supported. It will not be delivered.");
19470                     return ActivityManager.BROADCAST_SUCCESS;
19471             }
19472
19473             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19474                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19475                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19476                 final int uid = getUidFromIntent(intent);
19477                 if (uid != -1) {
19478                     final UidRecord uidRec = mActiveUids.get(uid);
19479                     if (uidRec != null) {
19480                         uidRec.updateHasInternetPermission();
19481                     }
19482                 }
19483             }
19484         }
19485
19486         // Add to the sticky list if requested.
19487         if (sticky) {
19488             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19489                     callingPid, callingUid)
19490                     != PackageManager.PERMISSION_GRANTED) {
19491                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19492                         + callingPid + ", uid=" + callingUid
19493                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19494                 Slog.w(TAG, msg);
19495                 throw new SecurityException(msg);
19496             }
19497             if (requiredPermissions != null && requiredPermissions.length > 0) {
19498                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19499                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19500                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19501             }
19502             if (intent.getComponent() != null) {
19503                 throw new SecurityException(
19504                         "Sticky broadcasts can't target a specific component");
19505             }
19506             // We use userId directly here, since the "all" target is maintained
19507             // as a separate set of sticky broadcasts.
19508             if (userId != UserHandle.USER_ALL) {
19509                 // But first, if this is not a broadcast to all users, then
19510                 // make sure it doesn't conflict with an existing broadcast to
19511                 // all users.
19512                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19513                         UserHandle.USER_ALL);
19514                 if (stickies != null) {
19515                     ArrayList<Intent> list = stickies.get(intent.getAction());
19516                     if (list != null) {
19517                         int N = list.size();
19518                         int i;
19519                         for (i=0; i<N; i++) {
19520                             if (intent.filterEquals(list.get(i))) {
19521                                 throw new IllegalArgumentException(
19522                                         "Sticky broadcast " + intent + " for user "
19523                                         + userId + " conflicts with existing global broadcast");
19524                             }
19525                         }
19526                     }
19527                 }
19528             }
19529             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19530             if (stickies == null) {
19531                 stickies = new ArrayMap<>();
19532                 mStickyBroadcasts.put(userId, stickies);
19533             }
19534             ArrayList<Intent> list = stickies.get(intent.getAction());
19535             if (list == null) {
19536                 list = new ArrayList<>();
19537                 stickies.put(intent.getAction(), list);
19538             }
19539             final int stickiesCount = list.size();
19540             int i;
19541             for (i = 0; i < stickiesCount; i++) {
19542                 if (intent.filterEquals(list.get(i))) {
19543                     // This sticky already exists, replace it.
19544                     list.set(i, new Intent(intent));
19545                     break;
19546                 }
19547             }
19548             if (i >= stickiesCount) {
19549                 list.add(new Intent(intent));
19550             }
19551         }
19552
19553         int[] users;
19554         if (userId == UserHandle.USER_ALL) {
19555             // Caller wants broadcast to go to all started users.
19556             users = mUserController.getStartedUserArrayLocked();
19557         } else {
19558             // Caller wants broadcast to go to one specific user.
19559             users = new int[] {userId};
19560         }
19561
19562         // Figure out who all will receive this broadcast.
19563         List receivers = null;
19564         List<BroadcastFilter> registeredReceivers = null;
19565         // Need to resolve the intent to interested receivers...
19566         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19567                  == 0) {
19568             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19569         }
19570         if (intent.getComponent() == null) {
19571             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19572                 // Query one target user at a time, excluding shell-restricted users
19573                 for (int i = 0; i < users.length; i++) {
19574                     if (mUserController.hasUserRestriction(
19575                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19576                         continue;
19577                     }
19578                     List<BroadcastFilter> registeredReceiversForUser =
19579                             mReceiverResolver.queryIntent(intent,
19580                                     resolvedType, false /*defaultOnly*/, users[i]);
19581                     if (registeredReceivers == null) {
19582                         registeredReceivers = registeredReceiversForUser;
19583                     } else if (registeredReceiversForUser != null) {
19584                         registeredReceivers.addAll(registeredReceiversForUser);
19585                     }
19586                 }
19587             } else {
19588                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19589                         resolvedType, false /*defaultOnly*/, userId);
19590             }
19591         }
19592
19593         final boolean replacePending =
19594                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19595
19596         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19597                 + " replacePending=" + replacePending);
19598
19599         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19600         if (!ordered && NR > 0) {
19601             // If we are not serializing this broadcast, then send the
19602             // registered receivers separately so they don't wait for the
19603             // components to be launched.
19604             if (isCallerSystem) {
19605                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19606                         isProtectedBroadcast, registeredReceivers);
19607             }
19608             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19609             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19610                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19611                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19612                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19613             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19614             final boolean replaced = replacePending
19615                     && (queue.replaceParallelBroadcastLocked(r) != null);
19616             // Note: We assume resultTo is null for non-ordered broadcasts.
19617             if (!replaced) {
19618                 queue.enqueueParallelBroadcastLocked(r);
19619                 queue.scheduleBroadcastsLocked();
19620             }
19621             registeredReceivers = null;
19622             NR = 0;
19623         }
19624
19625         // Merge into one list.
19626         int ir = 0;
19627         if (receivers != null) {
19628             // A special case for PACKAGE_ADDED: do not allow the package
19629             // being added to see this broadcast.  This prevents them from
19630             // using this as a back door to get run as soon as they are
19631             // installed.  Maybe in the future we want to have a special install
19632             // broadcast or such for apps, but we'd like to deliberately make
19633             // this decision.
19634             String skipPackages[] = null;
19635             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19636                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19637                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19638                 Uri data = intent.getData();
19639                 if (data != null) {
19640                     String pkgName = data.getSchemeSpecificPart();
19641                     if (pkgName != null) {
19642                         skipPackages = new String[] { pkgName };
19643                     }
19644                 }
19645             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19646                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19647             }
19648             if (skipPackages != null && (skipPackages.length > 0)) {
19649                 for (String skipPackage : skipPackages) {
19650                     if (skipPackage != null) {
19651                         int NT = receivers.size();
19652                         for (int it=0; it<NT; it++) {
19653                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19654                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19655                                 receivers.remove(it);
19656                                 it--;
19657                                 NT--;
19658                             }
19659                         }
19660                     }
19661                 }
19662             }
19663
19664             int NT = receivers != null ? receivers.size() : 0;
19665             int it = 0;
19666             ResolveInfo curt = null;
19667             BroadcastFilter curr = null;
19668             while (it < NT && ir < NR) {
19669                 if (curt == null) {
19670                     curt = (ResolveInfo)receivers.get(it);
19671                 }
19672                 if (curr == null) {
19673                     curr = registeredReceivers.get(ir);
19674                 }
19675                 if (curr.getPriority() >= curt.priority) {
19676                     // Insert this broadcast record into the final list.
19677                     receivers.add(it, curr);
19678                     ir++;
19679                     curr = null;
19680                     it++;
19681                     NT++;
19682                 } else {
19683                     // Skip to the next ResolveInfo in the final list.
19684                     it++;
19685                     curt = null;
19686                 }
19687             }
19688         }
19689         while (ir < NR) {
19690             if (receivers == null) {
19691                 receivers = new ArrayList();
19692             }
19693             receivers.add(registeredReceivers.get(ir));
19694             ir++;
19695         }
19696
19697         if (isCallerSystem) {
19698             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19699                     isProtectedBroadcast, receivers);
19700         }
19701
19702         if ((receivers != null && receivers.size() > 0)
19703                 || resultTo != null) {
19704             BroadcastQueue queue = broadcastQueueForIntent(intent);
19705             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19706                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19707                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19708                     resultData, resultExtras, ordered, sticky, false, userId);
19709
19710             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19711                     + ": prev had " + queue.mOrderedBroadcasts.size());
19712             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19713                     "Enqueueing broadcast " + r.intent.getAction());
19714
19715             final BroadcastRecord oldRecord =
19716                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19717             if (oldRecord != null) {
19718                 // Replaced, fire the result-to receiver.
19719                 if (oldRecord.resultTo != null) {
19720                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19721                     try {
19722                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19723                                 oldRecord.intent,
19724                                 Activity.RESULT_CANCELED, null, null,
19725                                 false, false, oldRecord.userId);
19726                     } catch (RemoteException e) {
19727                         Slog.w(TAG, "Failure ["
19728                                 + queue.mQueueName + "] sending broadcast result of "
19729                                 + intent, e);
19730
19731                     }
19732                 }
19733             } else {
19734                 queue.enqueueOrderedBroadcastLocked(r);
19735                 queue.scheduleBroadcastsLocked();
19736             }
19737         } else {
19738             // There was nobody interested in the broadcast, but we still want to record
19739             // that it happened.
19740             if (intent.getComponent() == null && intent.getPackage() == null
19741                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19742                 // This was an implicit broadcast... let's record it for posterity.
19743                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19744             }
19745         }
19746
19747         return ActivityManager.BROADCAST_SUCCESS;
19748     }
19749
19750     /**
19751      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19752      */
19753     private int getUidFromIntent(Intent intent) {
19754         if (intent == null) {
19755             return -1;
19756         }
19757         final Bundle intentExtras = intent.getExtras();
19758         return intent.hasExtra(Intent.EXTRA_UID)
19759                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19760     }
19761
19762     final void rotateBroadcastStatsIfNeededLocked() {
19763         final long now = SystemClock.elapsedRealtime();
19764         if (mCurBroadcastStats == null ||
19765                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19766             mLastBroadcastStats = mCurBroadcastStats;
19767             if (mLastBroadcastStats != null) {
19768                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19769                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19770             }
19771             mCurBroadcastStats = new BroadcastStats();
19772         }
19773     }
19774
19775     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19776             int skipCount, long dispatchTime) {
19777         rotateBroadcastStatsIfNeededLocked();
19778         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19779     }
19780
19781     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19782         rotateBroadcastStatsIfNeededLocked();
19783         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19784     }
19785
19786     final Intent verifyBroadcastLocked(Intent intent) {
19787         // Refuse possible leaked file descriptors
19788         if (intent != null && intent.hasFileDescriptors() == true) {
19789             throw new IllegalArgumentException("File descriptors passed in Intent");
19790         }
19791
19792         int flags = intent.getFlags();
19793
19794         if (!mProcessesReady) {
19795             // if the caller really truly claims to know what they're doing, go
19796             // ahead and allow the broadcast without launching any receivers
19797             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19798                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19799             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19800                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19801                         + " before boot completion");
19802                 throw new IllegalStateException("Cannot broadcast before boot completed");
19803             }
19804         }
19805
19806         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19807             throw new IllegalArgumentException(
19808                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19809         }
19810
19811         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19812             switch (Binder.getCallingUid()) {
19813                 case ROOT_UID:
19814                 case SHELL_UID:
19815                     break;
19816                 default:
19817                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19818                             + Binder.getCallingUid());
19819                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19820                     break;
19821             }
19822         }
19823
19824         return intent;
19825     }
19826
19827     public final int broadcastIntent(IApplicationThread caller,
19828             Intent intent, String resolvedType, IIntentReceiver resultTo,
19829             int resultCode, String resultData, Bundle resultExtras,
19830             String[] requiredPermissions, int appOp, Bundle bOptions,
19831             boolean serialized, boolean sticky, int userId) {
19832         enforceNotIsolatedCaller("broadcastIntent");
19833         synchronized(this) {
19834             intent = verifyBroadcastLocked(intent);
19835
19836             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19837             final int callingPid = Binder.getCallingPid();
19838             final int callingUid = Binder.getCallingUid();
19839             final long origId = Binder.clearCallingIdentity();
19840             int res = broadcastIntentLocked(callerApp,
19841                     callerApp != null ? callerApp.info.packageName : null,
19842                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19843                     requiredPermissions, appOp, bOptions, serialized, sticky,
19844                     callingPid, callingUid, userId);
19845             Binder.restoreCallingIdentity(origId);
19846             return res;
19847         }
19848     }
19849
19850
19851     int broadcastIntentInPackage(String packageName, int uid,
19852             Intent intent, String resolvedType, IIntentReceiver resultTo,
19853             int resultCode, String resultData, Bundle resultExtras,
19854             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19855             int userId) {
19856         synchronized(this) {
19857             intent = verifyBroadcastLocked(intent);
19858
19859             final long origId = Binder.clearCallingIdentity();
19860             String[] requiredPermissions = requiredPermission == null ? null
19861                     : new String[] {requiredPermission};
19862             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19863                     resultTo, resultCode, resultData, resultExtras,
19864                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19865                     sticky, -1, uid, userId);
19866             Binder.restoreCallingIdentity(origId);
19867             return res;
19868         }
19869     }
19870
19871     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19872         // Refuse possible leaked file descriptors
19873         if (intent != null && intent.hasFileDescriptors() == true) {
19874             throw new IllegalArgumentException("File descriptors passed in Intent");
19875         }
19876
19877         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19878                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19879
19880         synchronized(this) {
19881             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19882                     != PackageManager.PERMISSION_GRANTED) {
19883                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19884                         + Binder.getCallingPid()
19885                         + ", uid=" + Binder.getCallingUid()
19886                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19887                 Slog.w(TAG, msg);
19888                 throw new SecurityException(msg);
19889             }
19890             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19891             if (stickies != null) {
19892                 ArrayList<Intent> list = stickies.get(intent.getAction());
19893                 if (list != null) {
19894                     int N = list.size();
19895                     int i;
19896                     for (i=0; i<N; i++) {
19897                         if (intent.filterEquals(list.get(i))) {
19898                             list.remove(i);
19899                             break;
19900                         }
19901                     }
19902                     if (list.size() <= 0) {
19903                         stickies.remove(intent.getAction());
19904                     }
19905                 }
19906                 if (stickies.size() <= 0) {
19907                     mStickyBroadcasts.remove(userId);
19908                 }
19909             }
19910         }
19911     }
19912
19913     void backgroundServicesFinishedLocked(int userId) {
19914         for (BroadcastQueue queue : mBroadcastQueues) {
19915             queue.backgroundServicesFinishedLocked(userId);
19916         }
19917     }
19918
19919     public void finishReceiver(IBinder who, int resultCode, String resultData,
19920             Bundle resultExtras, boolean resultAbort, int flags) {
19921         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19922
19923         // Refuse possible leaked file descriptors
19924         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19925             throw new IllegalArgumentException("File descriptors passed in Bundle");
19926         }
19927
19928         final long origId = Binder.clearCallingIdentity();
19929         try {
19930             boolean doNext = false;
19931             BroadcastRecord r;
19932
19933             synchronized(this) {
19934                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19935                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19936                 r = queue.getMatchingOrderedReceiver(who);
19937                 if (r != null) {
19938                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19939                         resultData, resultExtras, resultAbort, true);
19940                 }
19941             }
19942
19943             if (doNext) {
19944                 r.queue.processNextBroadcast(false);
19945             }
19946             trimApplications();
19947         } finally {
19948             Binder.restoreCallingIdentity(origId);
19949         }
19950     }
19951
19952     // =========================================================
19953     // INSTRUMENTATION
19954     // =========================================================
19955
19956     public boolean startInstrumentation(ComponentName className,
19957             String profileFile, int flags, Bundle arguments,
19958             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19959             int userId, String abiOverride) {
19960         enforceNotIsolatedCaller("startInstrumentation");
19961         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19962                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19963         // Refuse possible leaked file descriptors
19964         if (arguments != null && arguments.hasFileDescriptors()) {
19965             throw new IllegalArgumentException("File descriptors passed in Bundle");
19966         }
19967
19968         synchronized(this) {
19969             InstrumentationInfo ii = null;
19970             ApplicationInfo ai = null;
19971             try {
19972                 ii = mContext.getPackageManager().getInstrumentationInfo(
19973                     className, STOCK_PM_FLAGS);
19974                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19975                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19976             } catch (PackageManager.NameNotFoundException e) {
19977             } catch (RemoteException e) {
19978             }
19979             if (ii == null) {
19980                 reportStartInstrumentationFailureLocked(watcher, className,
19981                         "Unable to find instrumentation info for: " + className);
19982                 return false;
19983             }
19984             if (ai == null) {
19985                 reportStartInstrumentationFailureLocked(watcher, className,
19986                         "Unable to find instrumentation target package: " + ii.targetPackage);
19987                 return false;
19988             }
19989             if (!ai.hasCode()) {
19990                 reportStartInstrumentationFailureLocked(watcher, className,
19991                         "Instrumentation target has no code: " + ii.targetPackage);
19992                 return false;
19993             }
19994
19995             int match = mContext.getPackageManager().checkSignatures(
19996                     ii.targetPackage, ii.packageName);
19997             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
19998                 String msg = "Permission Denial: starting instrumentation "
19999                         + className + " from pid="
20000                         + Binder.getCallingPid()
20001                         + ", uid=" + Binder.getCallingPid()
20002                         + " not allowed because package " + ii.packageName
20003                         + " does not have a signature matching the target "
20004                         + ii.targetPackage;
20005                 reportStartInstrumentationFailureLocked(watcher, className, msg);
20006                 throw new SecurityException(msg);
20007             }
20008
20009             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20010             activeInstr.mClass = className;
20011             String defProcess = ai.processName;;
20012             if (ii.targetProcesses == null) {
20013                 activeInstr.mTargetProcesses = new String[]{ai.processName};
20014             } else if (ii.targetProcesses.equals("*")) {
20015                 activeInstr.mTargetProcesses = new String[0];
20016             } else {
20017                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20018                 defProcess = activeInstr.mTargetProcesses[0];
20019             }
20020             activeInstr.mTargetInfo = ai;
20021             activeInstr.mProfileFile = profileFile;
20022             activeInstr.mArguments = arguments;
20023             activeInstr.mWatcher = watcher;
20024             activeInstr.mUiAutomationConnection = uiAutomationConnection;
20025             activeInstr.mResultClass = className;
20026
20027             final long origId = Binder.clearCallingIdentity();
20028             // Instrumentation can kill and relaunch even persistent processes
20029             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20030                     "start instr");
20031             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20032             app.instr = activeInstr;
20033             activeInstr.mFinished = false;
20034             activeInstr.mRunningProcesses.add(app);
20035             if (!mActiveInstrumentation.contains(activeInstr)) {
20036                 mActiveInstrumentation.add(activeInstr);
20037             }
20038             Binder.restoreCallingIdentity(origId);
20039         }
20040
20041         return true;
20042     }
20043
20044     /**
20045      * Report errors that occur while attempting to start Instrumentation.  Always writes the
20046      * error to the logs, but if somebody is watching, send the report there too.  This enables
20047      * the "am" command to report errors with more information.
20048      *
20049      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20050      * @param cn The component name of the instrumentation.
20051      * @param report The error report.
20052      */
20053     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20054             ComponentName cn, String report) {
20055         Slog.w(TAG, report);
20056         if (watcher != null) {
20057             Bundle results = new Bundle();
20058             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20059             results.putString("Error", report);
20060             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20061         }
20062     }
20063
20064     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20065         if (app.instr == null) {
20066             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20067             return;
20068         }
20069
20070         if (!app.instr.mFinished && results != null) {
20071             if (app.instr.mCurResults == null) {
20072                 app.instr.mCurResults = new Bundle(results);
20073             } else {
20074                 app.instr.mCurResults.putAll(results);
20075             }
20076         }
20077     }
20078
20079     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20080         int userId = UserHandle.getCallingUserId();
20081         // Refuse possible leaked file descriptors
20082         if (results != null && results.hasFileDescriptors()) {
20083             throw new IllegalArgumentException("File descriptors passed in Intent");
20084         }
20085
20086         synchronized(this) {
20087             ProcessRecord app = getRecordForAppLocked(target);
20088             if (app == null) {
20089                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20090                 return;
20091             }
20092             final long origId = Binder.clearCallingIdentity();
20093             addInstrumentationResultsLocked(app, results);
20094             Binder.restoreCallingIdentity(origId);
20095         }
20096     }
20097
20098     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20099         if (app.instr == null) {
20100             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20101             return;
20102         }
20103
20104         if (!app.instr.mFinished) {
20105             if (app.instr.mWatcher != null) {
20106                 Bundle finalResults = app.instr.mCurResults;
20107                 if (finalResults != null) {
20108                     if (app.instr.mCurResults != null && results != null) {
20109                         finalResults.putAll(results);
20110                     }
20111                 } else {
20112                     finalResults = results;
20113                 }
20114                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20115                         app.instr.mClass, resultCode, finalResults);
20116             }
20117
20118             // Can't call out of the system process with a lock held, so post a message.
20119             if (app.instr.mUiAutomationConnection != null) {
20120                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20121                         app.instr.mUiAutomationConnection).sendToTarget();
20122             }
20123             app.instr.mFinished = true;
20124         }
20125
20126         app.instr.removeProcess(app);
20127         app.instr = null;
20128
20129         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20130                 "finished inst");
20131     }
20132
20133     public void finishInstrumentation(IApplicationThread target,
20134             int resultCode, Bundle results) {
20135         int userId = UserHandle.getCallingUserId();
20136         // Refuse possible leaked file descriptors
20137         if (results != null && results.hasFileDescriptors()) {
20138             throw new IllegalArgumentException("File descriptors passed in Intent");
20139         }
20140
20141         synchronized(this) {
20142             ProcessRecord app = getRecordForAppLocked(target);
20143             if (app == null) {
20144                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20145                 return;
20146             }
20147             final long origId = Binder.clearCallingIdentity();
20148             finishInstrumentationLocked(app, resultCode, results);
20149             Binder.restoreCallingIdentity(origId);
20150         }
20151     }
20152
20153     // =========================================================
20154     // CONFIGURATION
20155     // =========================================================
20156
20157     public ConfigurationInfo getDeviceConfigurationInfo() {
20158         ConfigurationInfo config = new ConfigurationInfo();
20159         synchronized (this) {
20160             final Configuration globalConfig = getGlobalConfiguration();
20161             config.reqTouchScreen = globalConfig.touchscreen;
20162             config.reqKeyboardType = globalConfig.keyboard;
20163             config.reqNavigation = globalConfig.navigation;
20164             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20165                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20166                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20167             }
20168             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20169                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20170                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20171             }
20172             config.reqGlEsVersion = GL_ES_VERSION;
20173         }
20174         return config;
20175     }
20176
20177     ActivityStack getFocusedStack() {
20178         return mStackSupervisor.getFocusedStack();
20179     }
20180
20181     @Override
20182     public int getFocusedStackId() throws RemoteException {
20183         ActivityStack focusedStack = getFocusedStack();
20184         if (focusedStack != null) {
20185             return focusedStack.getStackId();
20186         }
20187         return -1;
20188     }
20189
20190     public Configuration getConfiguration() {
20191         Configuration ci;
20192         synchronized(this) {
20193             ci = new Configuration(getGlobalConfiguration());
20194             ci.userSetLocale = false;
20195         }
20196         return ci;
20197     }
20198
20199     @Override
20200     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20201         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20202         synchronized (this) {
20203             mSuppressResizeConfigChanges = suppress;
20204         }
20205     }
20206
20207     /**
20208      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20209      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20210      *       activity and clearing the task at the same time.
20211      */
20212     @Override
20213     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20214         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20215         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20216             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20217         }
20218         synchronized (this) {
20219             final long origId = Binder.clearCallingIdentity();
20220             try {
20221                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20222             } finally {
20223                 Binder.restoreCallingIdentity(origId);
20224             }
20225         }
20226     }
20227
20228     @Override
20229     public void updatePersistentConfiguration(Configuration values) {
20230         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20231         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20232         if (values == null) {
20233             throw new NullPointerException("Configuration must not be null");
20234         }
20235
20236         int userId = UserHandle.getCallingUserId();
20237
20238         synchronized(this) {
20239             updatePersistentConfigurationLocked(values, userId);
20240         }
20241     }
20242
20243     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20244         final long origId = Binder.clearCallingIdentity();
20245         try {
20246             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20247         } finally {
20248             Binder.restoreCallingIdentity(origId);
20249         }
20250     }
20251
20252     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20253         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20254                 FONT_SCALE, 1.0f, userId);
20255
20256         synchronized (this) {
20257             if (getGlobalConfiguration().fontScale == scaleFactor) {
20258                 return;
20259             }
20260
20261             final Configuration configuration
20262                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20263             configuration.fontScale = scaleFactor;
20264             updatePersistentConfigurationLocked(configuration, userId);
20265         }
20266     }
20267
20268     private void enforceWriteSettingsPermission(String func) {
20269         int uid = Binder.getCallingUid();
20270         if (uid == ROOT_UID) {
20271             return;
20272         }
20273
20274         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20275                 Settings.getPackageNameForUid(mContext, uid), false)) {
20276             return;
20277         }
20278
20279         String msg = "Permission Denial: " + func + " from pid="
20280                 + Binder.getCallingPid()
20281                 + ", uid=" + uid
20282                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20283         Slog.w(TAG, msg);
20284         throw new SecurityException(msg);
20285     }
20286
20287     @Override
20288     public boolean updateConfiguration(Configuration values) {
20289         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20290
20291         synchronized(this) {
20292             if (values == null && mWindowManager != null) {
20293                 // sentinel: fetch the current configuration from the window manager
20294                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20295             }
20296
20297             if (mWindowManager != null) {
20298                 // Update OOM levels based on display size.
20299                 mProcessList.applyDisplaySize(mWindowManager);
20300             }
20301
20302             final long origId = Binder.clearCallingIdentity();
20303             try {
20304                 if (values != null) {
20305                     Settings.System.clearConfiguration(values);
20306                 }
20307                 updateConfigurationLocked(values, null, false, false /* persistent */,
20308                         UserHandle.USER_NULL, false /* deferResume */,
20309                         mTmpUpdateConfigurationResult);
20310                 return mTmpUpdateConfigurationResult.changes != 0;
20311             } finally {
20312                 Binder.restoreCallingIdentity(origId);
20313             }
20314         }
20315     }
20316
20317     void updateUserConfigurationLocked() {
20318         final Configuration configuration = new Configuration(getGlobalConfiguration());
20319         final int currentUserId = mUserController.getCurrentUserIdLocked();
20320         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20321                 currentUserId, Settings.System.canWrite(mContext));
20322         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20323                 false /* persistent */, currentUserId, false /* deferResume */);
20324     }
20325
20326     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20327             boolean initLocale) {
20328         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20329     }
20330
20331     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20332             boolean initLocale, boolean deferResume) {
20333         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20334         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20335                 UserHandle.USER_NULL, deferResume);
20336     }
20337
20338     // To cache the list of supported system locales
20339     private String[] mSupportedSystemLocales = null;
20340
20341     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20342             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20343         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20344                 deferResume, null /* result */);
20345     }
20346
20347     /**
20348      * Do either or both things: (1) change the current configuration, and (2)
20349      * make sure the given activity is running with the (now) current
20350      * configuration.  Returns true if the activity has been left running, or
20351      * false if <var>starting</var> is being destroyed to match the new
20352      * configuration.
20353      *
20354      * @param userId is only used when persistent parameter is set to true to persist configuration
20355      *               for that particular user
20356      */
20357     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20358             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20359             UpdateConfigurationResult result) {
20360         int changes = 0;
20361         boolean kept = true;
20362
20363         if (mWindowManager != null) {
20364             mWindowManager.deferSurfaceLayout();
20365         }
20366         try {
20367             if (values != null) {
20368                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20369                         deferResume);
20370             }
20371
20372             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20373         } finally {
20374             if (mWindowManager != null) {
20375                 mWindowManager.continueSurfaceLayout();
20376             }
20377         }
20378
20379         if (result != null) {
20380             result.changes = changes;
20381             result.activityRelaunched = !kept;
20382         }
20383         return kept;
20384     }
20385
20386     /** Update default (global) configuration and notify listeners about changes. */
20387     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20388             boolean persistent, int userId, boolean deferResume) {
20389         mTempConfig.setTo(getGlobalConfiguration());
20390         final int changes = mTempConfig.updateFrom(values);
20391         if (changes == 0) {
20392             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20393             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20394             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20395             // (even if there are no actual changes) to unfreeze the window.
20396             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20397             return 0;
20398         }
20399
20400         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20401                 "Updating global configuration to: " + values);
20402
20403         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20404
20405         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20406             final LocaleList locales = values.getLocales();
20407             int bestLocaleIndex = 0;
20408             if (locales.size() > 1) {
20409                 if (mSupportedSystemLocales == null) {
20410                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20411                 }
20412                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20413             }
20414             SystemProperties.set("persist.sys.locale",
20415                     locales.get(bestLocaleIndex).toLanguageTag());
20416             LocaleList.setDefault(locales, bestLocaleIndex);
20417             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20418                     locales.get(bestLocaleIndex)));
20419         }
20420
20421         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20422         mTempConfig.seq = mConfigurationSeq;
20423
20424         // Update stored global config and notify everyone about the change.
20425         mStackSupervisor.onConfigurationChanged(mTempConfig);
20426
20427         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20428         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20429         mUsageStatsService.reportConfigurationChange(mTempConfig,
20430                 mUserController.getCurrentUserIdLocked());
20431
20432         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20433         mShowDialogs = shouldShowDialogs(mTempConfig);
20434
20435         AttributeCache ac = AttributeCache.instance();
20436         if (ac != null) {
20437             ac.updateConfiguration(mTempConfig);
20438         }
20439
20440         // Make sure all resources in our process are updated right now, so that anyone who is going
20441         // to retrieve resource values after we return will be sure to get the new ones. This is
20442         // especially important during boot, where the first config change needs to guarantee all
20443         // resources have that config before following boot code is executed.
20444         mSystemThread.applyConfigurationToResources(mTempConfig);
20445
20446         // We need another copy of global config because we're scheduling some calls instead of
20447         // running them in place. We need to be sure that object we send will be handled unchanged.
20448         final Configuration configCopy = new Configuration(mTempConfig);
20449         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20450             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20451             msg.obj = configCopy;
20452             msg.arg1 = userId;
20453             mHandler.sendMessage(msg);
20454         }
20455
20456         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20457             ProcessRecord app = mLruProcesses.get(i);
20458             try {
20459                 if (app.thread != null) {
20460                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20461                             + app.processName + " new config " + configCopy);
20462                     app.thread.scheduleConfigurationChanged(configCopy);
20463                 }
20464             } catch (Exception e) {
20465             }
20466         }
20467
20468         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20469         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20470                 | Intent.FLAG_RECEIVER_FOREGROUND
20471                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20472         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20473                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20474                 UserHandle.USER_ALL);
20475         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20476             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20477             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20478                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20479                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20480             if (initLocale || !mProcessesReady) {
20481                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20482             }
20483             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20484                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20485                     UserHandle.USER_ALL);
20486         }
20487
20488         // Override configuration of the default display duplicates global config, so we need to
20489         // update it also. This will also notify WindowManager about changes.
20490         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20491                 DEFAULT_DISPLAY);
20492
20493         return changes;
20494     }
20495
20496     @Override
20497     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20498         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20499
20500         synchronized (this) {
20501             // Check if display is initialized in AM.
20502             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20503                 // Call might come when display is not yet added or has already been removed.
20504                 if (DEBUG_CONFIGURATION) {
20505                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20506                             + displayId);
20507                 }
20508                 return false;
20509             }
20510
20511             if (values == null && mWindowManager != null) {
20512                 // sentinel: fetch the current configuration from the window manager
20513                 values = mWindowManager.computeNewConfiguration(displayId);
20514             }
20515
20516             if (mWindowManager != null) {
20517                 // Update OOM levels based on display size.
20518                 mProcessList.applyDisplaySize(mWindowManager);
20519             }
20520
20521             final long origId = Binder.clearCallingIdentity();
20522             try {
20523                 if (values != null) {
20524                     Settings.System.clearConfiguration(values);
20525                 }
20526                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20527                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20528                 return mTmpUpdateConfigurationResult.changes != 0;
20529             } finally {
20530                 Binder.restoreCallingIdentity(origId);
20531             }
20532         }
20533     }
20534
20535     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20536             boolean deferResume, int displayId) {
20537         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20538                 displayId, null /* result */);
20539     }
20540
20541     /**
20542      * Updates override configuration specific for the selected display. If no config is provided,
20543      * new one will be computed in WM based on current display info.
20544      */
20545     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20546             ActivityRecord starting, boolean deferResume, int displayId,
20547             UpdateConfigurationResult result) {
20548         int changes = 0;
20549         boolean kept = true;
20550
20551         if (mWindowManager != null) {
20552             mWindowManager.deferSurfaceLayout();
20553         }
20554         try {
20555             if (values != null) {
20556                 if (displayId == DEFAULT_DISPLAY) {
20557                     // Override configuration of the default display duplicates global config, so
20558                     // we're calling global config update instead for default display. It will also
20559                     // apply the correct override config.
20560                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20561                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20562                 } else {
20563                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20564                 }
20565             }
20566
20567             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20568         } finally {
20569             if (mWindowManager != null) {
20570                 mWindowManager.continueSurfaceLayout();
20571             }
20572         }
20573
20574         if (result != null) {
20575             result.changes = changes;
20576             result.activityRelaunched = !kept;
20577         }
20578         return kept;
20579     }
20580
20581     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20582             int displayId) {
20583         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20584         final int changes = mTempConfig.updateFrom(values);
20585         if (changes != 0) {
20586             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20587                     + mTempConfig + " for displayId=" + displayId);
20588             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20589
20590             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20591             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20592                 // Reset the unsupported display size dialog.
20593                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20594
20595                 killAllBackgroundProcessesExcept(N,
20596                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20597             }
20598         }
20599
20600         // Update the configuration with WM first and check if any of the stacks need to be resized
20601         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20602         // necessary. This way we don't need to relaunch again afterwards in
20603         // ensureActivityConfigurationLocked().
20604         if (mWindowManager != null) {
20605             final int[] resizedStacks =
20606                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20607             if (resizedStacks != null) {
20608                 for (int stackId : resizedStacks) {
20609                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20610                 }
20611             }
20612         }
20613
20614         return changes;
20615     }
20616
20617     /** Applies latest configuration and/or visibility updates if needed. */
20618     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20619         boolean kept = true;
20620         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20621         // mainStack is null during startup.
20622         if (mainStack != null) {
20623             if (changes != 0 && starting == null) {
20624                 // If the configuration changed, and the caller is not already
20625                 // in the process of starting an activity, then find the top
20626                 // activity to check if its configuration needs to change.
20627                 starting = mainStack.topRunningActivityLocked();
20628             }
20629
20630             if (starting != null) {
20631                 kept = starting.ensureActivityConfigurationLocked(changes,
20632                         false /* preserveWindow */);
20633                 // And we need to make sure at this point that all other activities
20634                 // are made visible with the correct configuration.
20635                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20636                         !PRESERVE_WINDOWS);
20637             }
20638         }
20639
20640         return kept;
20641     }
20642
20643     /** Helper method that requests bounds from WM and applies them to stack. */
20644     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20645         final Rect newStackBounds = new Rect();
20646         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20647         mStackSupervisor.resizeStackLocked(
20648                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20649                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20650                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20651     }
20652
20653     /**
20654      * Decide based on the configuration whether we should show the ANR,
20655      * crash, etc dialogs.  The idea is that if there is no affordance to
20656      * press the on-screen buttons, or the user experience would be more
20657      * greatly impacted than the crash itself, we shouldn't show the dialog.
20658      *
20659      * A thought: SystemUI might also want to get told about this, the Power
20660      * dialog / global actions also might want different behaviors.
20661      */
20662     private static boolean shouldShowDialogs(Configuration config) {
20663         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20664                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20665                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20666         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20667         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20668                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20669                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20670                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20671         return inputMethodExists && uiModeSupportsDialogs;
20672     }
20673
20674     @Override
20675     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20676         synchronized (this) {
20677             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20678             if (srec != null) {
20679                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20680             }
20681         }
20682         return false;
20683     }
20684
20685     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20686             Intent resultData) {
20687
20688         synchronized (this) {
20689             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20690             if (r != null) {
20691                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20692             }
20693             return false;
20694         }
20695     }
20696
20697     public int getLaunchedFromUid(IBinder activityToken) {
20698         ActivityRecord srec;
20699         synchronized (this) {
20700             srec = ActivityRecord.forTokenLocked(activityToken);
20701         }
20702         if (srec == null) {
20703             return -1;
20704         }
20705         return srec.launchedFromUid;
20706     }
20707
20708     public String getLaunchedFromPackage(IBinder activityToken) {
20709         ActivityRecord srec;
20710         synchronized (this) {
20711             srec = ActivityRecord.forTokenLocked(activityToken);
20712         }
20713         if (srec == null) {
20714             return null;
20715         }
20716         return srec.launchedFromPackage;
20717     }
20718
20719     // =========================================================
20720     // LIFETIME MANAGEMENT
20721     // =========================================================
20722
20723     // Returns whether the app is receiving broadcast.
20724     // If receiving, fetch all broadcast queues which the app is
20725     // the current [or imminent] receiver on.
20726     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20727             ArraySet<BroadcastQueue> receivingQueues) {
20728         if (!app.curReceivers.isEmpty()) {
20729             for (BroadcastRecord r : app.curReceivers) {
20730                 receivingQueues.add(r.queue);
20731             }
20732             return true;
20733         }
20734
20735         // It's not the current receiver, but it might be starting up to become one
20736         for (BroadcastQueue queue : mBroadcastQueues) {
20737             final BroadcastRecord r = queue.mPendingBroadcast;
20738             if (r != null && r.curApp == app) {
20739                 // found it; report which queue it's in
20740                 receivingQueues.add(queue);
20741             }
20742         }
20743
20744         return !receivingQueues.isEmpty();
20745     }
20746
20747     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20748             int targetUid, ComponentName targetComponent, String targetProcess) {
20749         if (!mTrackingAssociations) {
20750             return null;
20751         }
20752         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20753                 = mAssociations.get(targetUid);
20754         if (components == null) {
20755             components = new ArrayMap<>();
20756             mAssociations.put(targetUid, components);
20757         }
20758         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20759         if (sourceUids == null) {
20760             sourceUids = new SparseArray<>();
20761             components.put(targetComponent, sourceUids);
20762         }
20763         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20764         if (sourceProcesses == null) {
20765             sourceProcesses = new ArrayMap<>();
20766             sourceUids.put(sourceUid, sourceProcesses);
20767         }
20768         Association ass = sourceProcesses.get(sourceProcess);
20769         if (ass == null) {
20770             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20771                     targetProcess);
20772             sourceProcesses.put(sourceProcess, ass);
20773         }
20774         ass.mCount++;
20775         ass.mNesting++;
20776         if (ass.mNesting == 1) {
20777             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20778             ass.mLastState = sourceState;
20779         }
20780         return ass;
20781     }
20782
20783     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20784             ComponentName targetComponent) {
20785         if (!mTrackingAssociations) {
20786             return;
20787         }
20788         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20789                 = mAssociations.get(targetUid);
20790         if (components == null) {
20791             return;
20792         }
20793         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20794         if (sourceUids == null) {
20795             return;
20796         }
20797         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20798         if (sourceProcesses == null) {
20799             return;
20800         }
20801         Association ass = sourceProcesses.get(sourceProcess);
20802         if (ass == null || ass.mNesting <= 0) {
20803             return;
20804         }
20805         ass.mNesting--;
20806         if (ass.mNesting == 0) {
20807             long uptime = SystemClock.uptimeMillis();
20808             ass.mTime += uptime - ass.mStartTime;
20809             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20810                     += uptime - ass.mLastStateUptime;
20811             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20812         }
20813     }
20814
20815     private void noteUidProcessState(final int uid, final int state) {
20816         mBatteryStatsService.noteUidProcessState(uid, state);
20817         if (mTrackingAssociations) {
20818             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20819                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20820                         = mAssociations.valueAt(i1);
20821                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20822                     SparseArray<ArrayMap<String, Association>> sourceUids
20823                             = targetComponents.valueAt(i2);
20824                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20825                     if (sourceProcesses != null) {
20826                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20827                             Association ass = sourceProcesses.valueAt(i4);
20828                             if (ass.mNesting >= 1) {
20829                                 // currently associated
20830                                 long uptime = SystemClock.uptimeMillis();
20831                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20832                                         += uptime - ass.mLastStateUptime;
20833                                 ass.mLastState = state;
20834                                 ass.mLastStateUptime = uptime;
20835                             }
20836                         }
20837                     }
20838                 }
20839             }
20840         }
20841     }
20842
20843     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20844             boolean doingAll, long now) {
20845         if (mAdjSeq == app.adjSeq) {
20846             // This adjustment has already been computed.
20847             return app.curRawAdj;
20848         }
20849
20850         if (app.thread == null) {
20851             app.adjSeq = mAdjSeq;
20852             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20853             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20854             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20855         }
20856
20857         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20858         app.adjSource = null;
20859         app.adjTarget = null;
20860         app.empty = false;
20861         app.cached = false;
20862
20863         final int activitiesSize = app.activities.size();
20864
20865         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20866             // The max adjustment doesn't allow this app to be anything
20867             // below foreground, so it is not worth doing work for it.
20868             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20869             app.adjType = "fixed";
20870             app.adjSeq = mAdjSeq;
20871             app.curRawAdj = app.maxAdj;
20872             app.foregroundActivities = false;
20873             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20874             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20875             // System processes can do UI, and when they do we want to have
20876             // them trim their memory after the user leaves the UI.  To
20877             // facilitate this, here we need to determine whether or not it
20878             // is currently showing UI.
20879             app.systemNoUi = true;
20880             if (app == TOP_APP) {
20881                 app.systemNoUi = false;
20882                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20883                 app.adjType = "pers-top-activity";
20884             } else if (app.hasTopUi) {
20885                 app.systemNoUi = false;
20886                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20887                 app.adjType = "pers-top-ui";
20888             } else if (activitiesSize > 0) {
20889                 for (int j = 0; j < activitiesSize; j++) {
20890                     final ActivityRecord r = app.activities.get(j);
20891                     if (r.visible) {
20892                         app.systemNoUi = false;
20893                     }
20894                 }
20895             }
20896             if (!app.systemNoUi) {
20897                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20898             }
20899             return (app.curAdj=app.maxAdj);
20900         }
20901
20902         app.systemNoUi = false;
20903
20904         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20905
20906         // Determine the importance of the process, starting with most
20907         // important to least, and assign an appropriate OOM adjustment.
20908         int adj;
20909         int schedGroup;
20910         int procState;
20911         boolean foregroundActivities = false;
20912         mTmpBroadcastQueue.clear();
20913         if (app == TOP_APP) {
20914             // The last app on the list is the foreground app.
20915             adj = ProcessList.FOREGROUND_APP_ADJ;
20916             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20917             app.adjType = "top-activity";
20918             foregroundActivities = true;
20919             procState = PROCESS_STATE_CUR_TOP;
20920             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20921         } else if (app.instr != null) {
20922             // Don't want to kill running instrumentation.
20923             adj = ProcessList.FOREGROUND_APP_ADJ;
20924             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20925             app.adjType = "instrumentation";
20926             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20927             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20928         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20929             // An app that is currently receiving a broadcast also
20930             // counts as being in the foreground for OOM killer purposes.
20931             // It's placed in a sched group based on the nature of the
20932             // broadcast as reflected by which queue it's active in.
20933             adj = ProcessList.FOREGROUND_APP_ADJ;
20934             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20935                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20936             app.adjType = "broadcast";
20937             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20938             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20939         } else if (app.executingServices.size() > 0) {
20940             // An app that is currently executing a service callback also
20941             // counts as being in the foreground.
20942             adj = ProcessList.FOREGROUND_APP_ADJ;
20943             schedGroup = app.execServicesFg ?
20944                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20945             app.adjType = "exec-service";
20946             procState = ActivityManager.PROCESS_STATE_SERVICE;
20947             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20948             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20949         } else {
20950             // As far as we know the process is empty.  We may change our mind later.
20951             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20952             // At this point we don't actually know the adjustment.  Use the cached adj
20953             // value that the caller wants us to.
20954             adj = cachedAdj;
20955             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20956             app.cached = true;
20957             app.empty = true;
20958             app.adjType = "cch-empty";
20959             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20960         }
20961
20962         // Examine all activities if not already foreground.
20963         if (!foregroundActivities && activitiesSize > 0) {
20964             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20965             for (int j = 0; j < activitiesSize; j++) {
20966                 final ActivityRecord r = app.activities.get(j);
20967                 if (r.app != app) {
20968                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20969                             + " instead of expected " + app);
20970                     if (r.app == null || (r.app.uid == app.uid)) {
20971                         // Only fix things up when they look sane
20972                         r.app = app;
20973                     } else {
20974                         continue;
20975                     }
20976                 }
20977                 if (r.visible) {
20978                     // App has a visible activity; only upgrade adjustment.
20979                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20980                         adj = ProcessList.VISIBLE_APP_ADJ;
20981                         app.adjType = "vis-activity";
20982                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20983                     }
20984                     if (procState > PROCESS_STATE_CUR_TOP) {
20985                         procState = PROCESS_STATE_CUR_TOP;
20986                         app.adjType = "vis-activity";
20987                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20988                     }
20989                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20990                     app.cached = false;
20991                     app.empty = false;
20992                     foregroundActivities = true;
20993                     final TaskRecord task = r.getTask();
20994                     if (task != null && minLayer > 0) {
20995                         final int layer = task.mLayerRank;
20996                         if (layer >= 0 && minLayer > layer) {
20997                             minLayer = layer;
20998                         }
20999                     }
21000                     break;
21001                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21002                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21003                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21004                         app.adjType = "pause-activity";
21005                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21006                     }
21007                     if (procState > PROCESS_STATE_CUR_TOP) {
21008                         procState = PROCESS_STATE_CUR_TOP;
21009                         app.adjType = "pause-activity";
21010                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21011                     }
21012                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21013                     app.cached = false;
21014                     app.empty = false;
21015                     foregroundActivities = true;
21016                 } else if (r.state == ActivityState.STOPPING) {
21017                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21018                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21019                         app.adjType = "stop-activity";
21020                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21021                     }
21022                     // For the process state, we will at this point consider the
21023                     // process to be cached.  It will be cached either as an activity
21024                     // or empty depending on whether the activity is finishing.  We do
21025                     // this so that we can treat the process as cached for purposes of
21026                     // memory trimming (determing current memory level, trim command to
21027                     // send to process) since there can be an arbitrary number of stopping
21028                     // processes and they should soon all go into the cached state.
21029                     if (!r.finishing) {
21030                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21031                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21032                             app.adjType = "stop-activity";
21033                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21034                         }
21035                     }
21036                     app.cached = false;
21037                     app.empty = false;
21038                     foregroundActivities = true;
21039                 } else {
21040                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21041                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21042                         app.adjType = "cch-act";
21043                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21044                     }
21045                 }
21046             }
21047             if (adj == ProcessList.VISIBLE_APP_ADJ) {
21048                 adj += minLayer;
21049             }
21050         }
21051
21052         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21053                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21054             if (app.foregroundServices) {
21055                 // The user is aware of this app, so make it visible.
21056                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21057                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21058                 app.cached = false;
21059                 app.adjType = "fg-service";
21060                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21061                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21062             } else if (app.hasOverlayUi) {
21063                 // The process is display an overlay UI.
21064                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21065                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21066                 app.cached = false;
21067                 app.adjType = "has-overlay-ui";
21068                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21069                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21070             }
21071         }
21072
21073         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21074                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21075             if (app.forcingToImportant != null) {
21076                 // This is currently used for toasts...  they are not interactive, and
21077                 // we don't want them to cause the app to become fully foreground (and
21078                 // thus out of background check), so we yes the best background level we can.
21079                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21080                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21081                 app.cached = false;
21082                 app.adjType = "force-imp";
21083                 app.adjSource = app.forcingToImportant;
21084                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21085                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21086             }
21087         }
21088
21089         if (app == mHeavyWeightProcess) {
21090             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21091                 // We don't want to kill the current heavy-weight process.
21092                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21093                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21094                 app.cached = false;
21095                 app.adjType = "heavy";
21096                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21097             }
21098             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21099                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21100                 app.adjType = "heavy";
21101                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21102             }
21103         }
21104
21105         if (app == mHomeProcess) {
21106             if (adj > ProcessList.HOME_APP_ADJ) {
21107                 // This process is hosting what we currently consider to be the
21108                 // home app, so we don't want to let it go into the background.
21109                 adj = ProcessList.HOME_APP_ADJ;
21110                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21111                 app.cached = false;
21112                 app.adjType = "home";
21113                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21114             }
21115             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21116                 procState = ActivityManager.PROCESS_STATE_HOME;
21117                 app.adjType = "home";
21118                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21119             }
21120         }
21121
21122         if (app == mPreviousProcess && app.activities.size() > 0) {
21123             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21124                 // This was the previous process that showed UI to the user.
21125                 // We want to try to keep it around more aggressively, to give
21126                 // a good experience around switching between two apps.
21127                 adj = ProcessList.PREVIOUS_APP_ADJ;
21128                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21129                 app.cached = false;
21130                 app.adjType = "previous";
21131                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21132             }
21133             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21134                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21135                 app.adjType = "previous";
21136                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21137             }
21138         }
21139
21140         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21141                 + " reason=" + app.adjType);
21142
21143         // By default, we use the computed adjustment.  It may be changed if
21144         // there are applications dependent on our services or providers, but
21145         // this gives us a baseline and makes sure we don't get into an
21146         // infinite recursion.
21147         app.adjSeq = mAdjSeq;
21148         app.curRawAdj = adj;
21149         app.hasStartedServices = false;
21150
21151         if (mBackupTarget != null && app == mBackupTarget.app) {
21152             // If possible we want to avoid killing apps while they're being backed up
21153             if (adj > ProcessList.BACKUP_APP_ADJ) {
21154                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21155                 adj = ProcessList.BACKUP_APP_ADJ;
21156                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21157                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21158                 }
21159                 app.adjType = "backup";
21160                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21161                 app.cached = false;
21162             }
21163             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21164                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21165                 app.adjType = "backup";
21166                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21167             }
21168         }
21169
21170         boolean mayBeTop = false;
21171         String mayBeTopType = null;
21172         Object mayBeTopSource = null;
21173         Object mayBeTopTarget = null;
21174
21175         for (int is = app.services.size()-1;
21176                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21177                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21178                         || procState > ActivityManager.PROCESS_STATE_TOP);
21179                 is--) {
21180             ServiceRecord s = app.services.valueAt(is);
21181             if (s.startRequested) {
21182                 app.hasStartedServices = true;
21183                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21184                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21185                     app.adjType = "started-services";
21186                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21187                 }
21188                 if (app.hasShownUi && app != mHomeProcess) {
21189                     // If this process has shown some UI, let it immediately
21190                     // go to the LRU list because it may be pretty heavy with
21191                     // UI stuff.  We'll tag it with a label just to help
21192                     // debug and understand what is going on.
21193                     if (adj > ProcessList.SERVICE_ADJ) {
21194                         app.adjType = "cch-started-ui-services";
21195                     }
21196                 } else {
21197                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21198                         // This service has seen some activity within
21199                         // recent memory, so we will keep its process ahead
21200                         // of the background processes.
21201                         if (adj > ProcessList.SERVICE_ADJ) {
21202                             adj = ProcessList.SERVICE_ADJ;
21203                             app.adjType = "started-services";
21204                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21205                             app.cached = false;
21206                         }
21207                     }
21208                     // If we have let the service slide into the background
21209                     // state, still have some text describing what it is doing
21210                     // even though the service no longer has an impact.
21211                     if (adj > ProcessList.SERVICE_ADJ) {
21212                         app.adjType = "cch-started-services";
21213                     }
21214                 }
21215             }
21216
21217             for (int conni = s.connections.size()-1;
21218                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21219                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21220                             || procState > ActivityManager.PROCESS_STATE_TOP);
21221                     conni--) {
21222                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21223                 for (int i = 0;
21224                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21225                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21226                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21227                         i++) {
21228                     // XXX should compute this based on the max of
21229                     // all connected clients.
21230                     ConnectionRecord cr = clist.get(i);
21231                     if (cr.binding.client == app) {
21232                         // Binding to ourself is not interesting.
21233                         continue;
21234                     }
21235
21236                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21237                         ProcessRecord client = cr.binding.client;
21238                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21239                                 TOP_APP, doingAll, now);
21240                         int clientProcState = client.curProcState;
21241                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21242                             // If the other app is cached for any reason, for purposes here
21243                             // we are going to consider it empty.  The specific cached state
21244                             // doesn't propagate except under certain conditions.
21245                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21246                         }
21247                         String adjType = null;
21248                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21249                             // Not doing bind OOM management, so treat
21250                             // this guy more like a started service.
21251                             if (app.hasShownUi && app != mHomeProcess) {
21252                                 // If this process has shown some UI, let it immediately
21253                                 // go to the LRU list because it may be pretty heavy with
21254                                 // UI stuff.  We'll tag it with a label just to help
21255                                 // debug and understand what is going on.
21256                                 if (adj > clientAdj) {
21257                                     adjType = "cch-bound-ui-services";
21258                                 }
21259                                 app.cached = false;
21260                                 clientAdj = adj;
21261                                 clientProcState = procState;
21262                             } else {
21263                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21264                                     // This service has not seen activity within
21265                                     // recent memory, so allow it to drop to the
21266                                     // LRU list if there is no other reason to keep
21267                                     // it around.  We'll also tag it with a label just
21268                                     // to help debug and undertand what is going on.
21269                                     if (adj > clientAdj) {
21270                                         adjType = "cch-bound-services";
21271                                     }
21272                                     clientAdj = adj;
21273                                 }
21274                             }
21275                         }
21276                         if (adj > clientAdj) {
21277                             // If this process has recently shown UI, and
21278                             // the process that is binding to it is less
21279                             // important than being visible, then we don't
21280                             // care about the binding as much as we care
21281                             // about letting this process get into the LRU
21282                             // list to be killed and restarted if needed for
21283                             // memory.
21284                             if (app.hasShownUi && app != mHomeProcess
21285                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21286                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21287                                     adjType = "cch-bound-ui-services";
21288                                 }
21289                             } else {
21290                                 int newAdj;
21291                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21292                                         |Context.BIND_IMPORTANT)) != 0) {
21293                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21294                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21295                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21296                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21297                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21298                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21299                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21300                                     newAdj = clientAdj;
21301                                 } else {
21302                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21303                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21304                                     } else {
21305                                         newAdj = adj;
21306                                     }
21307                                 }
21308                                 if (!client.cached) {
21309                                     app.cached = false;
21310                                 }
21311                                 if (adj >  newAdj) {
21312                                     adj = newAdj;
21313                                     adjType = "service";
21314                                 }
21315                             }
21316                         }
21317                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21318                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21319                             // This will treat important bound services identically to
21320                             // the top app, which may behave differently than generic
21321                             // foreground work.
21322                             if (client.curSchedGroup > schedGroup) {
21323                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21324                                     schedGroup = client.curSchedGroup;
21325                                 } else {
21326                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21327                                 }
21328                             }
21329                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21330                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21331                                     // Special handling of clients who are in the top state.
21332                                     // We *may* want to consider this process to be in the
21333                                     // top state as well, but only if there is not another
21334                                     // reason for it to be running.  Being on the top is a
21335                                     // special state, meaning you are specifically running
21336                                     // for the current top app.  If the process is already
21337                                     // running in the background for some other reason, it
21338                                     // is more important to continue considering it to be
21339                                     // in the background state.
21340                                     mayBeTop = true;
21341                                     mayBeTopType = "service";
21342                                     mayBeTopSource = cr.binding.client;
21343                                     mayBeTopTarget = s.name;
21344                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21345                                 } else {
21346                                     // Special handling for above-top states (persistent
21347                                     // processes).  These should not bring the current process
21348                                     // into the top state, since they are not on top.  Instead
21349                                     // give them the best state after that.
21350                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21351                                         clientProcState =
21352                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21353                                     } else if (mWakefulness
21354                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21355                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21356                                                     != 0) {
21357                                         clientProcState =
21358                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21359                                     } else {
21360                                         clientProcState =
21361                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21362                                     }
21363                                 }
21364                             }
21365                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21366                             if (clientProcState <
21367                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21368                                 clientProcState =
21369                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21370                             }
21371                         } else {
21372                             if (clientProcState <
21373                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21374                                 clientProcState =
21375                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21376                             }
21377                         }
21378                         if (procState > clientProcState) {
21379                             procState = clientProcState;
21380                             if (adjType == null) {
21381                                 adjType = "service";
21382                             }
21383                         }
21384                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21385                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21386                             app.pendingUiClean = true;
21387                         }
21388                         if (adjType != null) {
21389                             app.adjType = adjType;
21390                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21391                                     .REASON_SERVICE_IN_USE;
21392                             app.adjSource = cr.binding.client;
21393                             app.adjSourceProcState = clientProcState;
21394                             app.adjTarget = s.name;
21395                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21396                                     + ": " + app + ", due to " + cr.binding.client
21397                                     + " adj=" + adj + " procState=" + procState);
21398                         }
21399                     }
21400                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21401                         app.treatLikeActivity = true;
21402                     }
21403                     final ActivityRecord a = cr.activity;
21404                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21405                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21406                             (a.visible || a.state == ActivityState.RESUMED ||
21407                              a.state == ActivityState.PAUSING)) {
21408                             adj = ProcessList.FOREGROUND_APP_ADJ;
21409                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21410                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21411                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21412                                 } else {
21413                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21414                                 }
21415                             }
21416                             app.cached = false;
21417                             app.adjType = "service";
21418                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21419                                     .REASON_SERVICE_IN_USE;
21420                             app.adjSource = a;
21421                             app.adjSourceProcState = procState;
21422                             app.adjTarget = s.name;
21423                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21424                                     + app);
21425                         }
21426                     }
21427                 }
21428             }
21429         }
21430
21431         for (int provi = app.pubProviders.size()-1;
21432                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21433                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21434                         || procState > ActivityManager.PROCESS_STATE_TOP);
21435                 provi--) {
21436             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21437             for (int i = cpr.connections.size()-1;
21438                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21439                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21440                             || procState > ActivityManager.PROCESS_STATE_TOP);
21441                     i--) {
21442                 ContentProviderConnection conn = cpr.connections.get(i);
21443                 ProcessRecord client = conn.client;
21444                 if (client == app) {
21445                     // Being our own client is not interesting.
21446                     continue;
21447                 }
21448                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21449                 int clientProcState = client.curProcState;
21450                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21451                     // If the other app is cached for any reason, for purposes here
21452                     // we are going to consider it empty.
21453                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21454                 }
21455                 String adjType = null;
21456                 if (adj > clientAdj) {
21457                     if (app.hasShownUi && app != mHomeProcess
21458                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21459                         adjType = "cch-ui-provider";
21460                     } else {
21461                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21462                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21463                         adjType = "provider";
21464                     }
21465                     app.cached &= client.cached;
21466                 }
21467                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21468                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21469                         // Special handling of clients who are in the top state.
21470                         // We *may* want to consider this process to be in the
21471                         // top state as well, but only if there is not another
21472                         // reason for it to be running.  Being on the top is a
21473                         // special state, meaning you are specifically running
21474                         // for the current top app.  If the process is already
21475                         // running in the background for some other reason, it
21476                         // is more important to continue considering it to be
21477                         // in the background state.
21478                         mayBeTop = true;
21479                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21480                         mayBeTopType = adjType = "provider-top";
21481                         mayBeTopSource = client;
21482                         mayBeTopTarget = cpr.name;
21483                     } else {
21484                         // Special handling for above-top states (persistent
21485                         // processes).  These should not bring the current process
21486                         // into the top state, since they are not on top.  Instead
21487                         // give them the best state after that.
21488                         clientProcState =
21489                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21490                         if (adjType == null) {
21491                             adjType = "provider";
21492                         }
21493                     }
21494                 }
21495                 if (procState > clientProcState) {
21496                     procState = clientProcState;
21497                 }
21498                 if (client.curSchedGroup > schedGroup) {
21499                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21500                 }
21501                 if (adjType != null) {
21502                     app.adjType = adjType;
21503                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21504                             .REASON_PROVIDER_IN_USE;
21505                     app.adjSource = client;
21506                     app.adjSourceProcState = clientProcState;
21507                     app.adjTarget = cpr.name;
21508                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21509                             + ": " + app + ", due to " + client
21510                             + " adj=" + adj + " procState=" + procState);
21511                 }
21512             }
21513             // If the provider has external (non-framework) process
21514             // dependencies, ensure that its adjustment is at least
21515             // FOREGROUND_APP_ADJ.
21516             if (cpr.hasExternalProcessHandles()) {
21517                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21518                     adj = ProcessList.FOREGROUND_APP_ADJ;
21519                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21520                     app.cached = false;
21521                     app.adjType = "ext-provider";
21522                     app.adjTarget = cpr.name;
21523                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21524                 }
21525                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21526                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21527                 }
21528             }
21529         }
21530
21531         if (app.lastProviderTime > 0 &&
21532                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21533             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21534                 adj = ProcessList.PREVIOUS_APP_ADJ;
21535                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21536                 app.cached = false;
21537                 app.adjType = "recent-provider";
21538                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21539             }
21540             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21541                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21542                 app.adjType = "recent-provider";
21543                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21544             }
21545         }
21546
21547         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21548             // A client of one of our services or providers is in the top state.  We
21549             // *may* want to be in the top state, but not if we are already running in
21550             // the background for some other reason.  For the decision here, we are going
21551             // to pick out a few specific states that we want to remain in when a client
21552             // is top (states that tend to be longer-term) and otherwise allow it to go
21553             // to the top state.
21554             switch (procState) {
21555                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21556                     // Something else is keeping it at this level, just leave it.
21557                     break;
21558                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21559                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21560                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21561                 case ActivityManager.PROCESS_STATE_SERVICE:
21562                     // These all are longer-term states, so pull them up to the top
21563                     // of the background states, but not all the way to the top state.
21564                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21565                     app.adjType = mayBeTopType;
21566                     app.adjSource = mayBeTopSource;
21567                     app.adjTarget = mayBeTopTarget;
21568                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21569                             + ": " + app + ", due to " + mayBeTopSource
21570                             + " adj=" + adj + " procState=" + procState);
21571                     break;
21572                 default:
21573                     // Otherwise, top is a better choice, so take it.
21574                     procState = ActivityManager.PROCESS_STATE_TOP;
21575                     app.adjType = mayBeTopType;
21576                     app.adjSource = mayBeTopSource;
21577                     app.adjTarget = mayBeTopTarget;
21578                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21579                             + ": " + app + ", due to " + mayBeTopSource
21580                             + " adj=" + adj + " procState=" + procState);
21581                     break;
21582             }
21583         }
21584
21585         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21586             if (app.hasClientActivities) {
21587                 // This is a cached process, but with client activities.  Mark it so.
21588                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21589                 app.adjType = "cch-client-act";
21590             } else if (app.treatLikeActivity) {
21591                 // This is a cached process, but somebody wants us to treat it like it has
21592                 // an activity, okay!
21593                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21594                 app.adjType = "cch-as-act";
21595             }
21596         }
21597
21598         if (adj == ProcessList.SERVICE_ADJ) {
21599             if (doingAll) {
21600                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21601                 mNewNumServiceProcs++;
21602                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21603                 if (!app.serviceb) {
21604                     // This service isn't far enough down on the LRU list to
21605                     // normally be a B service, but if we are low on RAM and it
21606                     // is large we want to force it down since we would prefer to
21607                     // keep launcher over it.
21608                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21609                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21610                         app.serviceHighRam = true;
21611                         app.serviceb = true;
21612                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21613                     } else {
21614                         mNewNumAServiceProcs++;
21615                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21616                     }
21617                 } else {
21618                     app.serviceHighRam = false;
21619                 }
21620             }
21621             if (app.serviceb) {
21622                 adj = ProcessList.SERVICE_B_ADJ;
21623             }
21624         }
21625
21626         app.curRawAdj = adj;
21627
21628         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21629         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21630         if (adj > app.maxAdj) {
21631             adj = app.maxAdj;
21632             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21633                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21634             }
21635         }
21636
21637         // Do final modification to adj.  Everything we do between here and applying
21638         // the final setAdj must be done in this function, because we will also use
21639         // it when computing the final cached adj later.  Note that we don't need to
21640         // worry about this for max adj above, since max adj will always be used to
21641         // keep it out of the cached vaues.
21642         app.curAdj = app.modifyRawOomAdj(adj);
21643         app.curSchedGroup = schedGroup;
21644         app.curProcState = procState;
21645         app.foregroundActivities = foregroundActivities;
21646
21647         return app.curRawAdj;
21648     }
21649
21650     /**
21651      * Record new PSS sample for a process.
21652      */
21653     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21654             long now) {
21655         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21656                 swapPss * 1024);
21657         proc.lastPssTime = now;
21658         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21659         if (DEBUG_PSS) Slog.d(TAG_PSS,
21660                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21661                 + " state=" + ProcessList.makeProcStateString(procState));
21662         if (proc.initialIdlePss == 0) {
21663             proc.initialIdlePss = pss;
21664         }
21665         proc.lastPss = pss;
21666         proc.lastSwapPss = swapPss;
21667         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21668             proc.lastCachedPss = pss;
21669             proc.lastCachedSwapPss = swapPss;
21670         }
21671
21672         final SparseArray<Pair<Long, String>> watchUids
21673                 = mMemWatchProcesses.getMap().get(proc.processName);
21674         Long check = null;
21675         if (watchUids != null) {
21676             Pair<Long, String> val = watchUids.get(proc.uid);
21677             if (val == null) {
21678                 val = watchUids.get(0);
21679             }
21680             if (val != null) {
21681                 check = val.first;
21682             }
21683         }
21684         if (check != null) {
21685             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21686                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21687                 if (!isDebuggable) {
21688                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21689                         isDebuggable = true;
21690                     }
21691                 }
21692                 if (isDebuggable) {
21693                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21694                     final ProcessRecord myProc = proc;
21695                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21696                     mMemWatchDumpProcName = proc.processName;
21697                     mMemWatchDumpFile = heapdumpFile.toString();
21698                     mMemWatchDumpPid = proc.pid;
21699                     mMemWatchDumpUid = proc.uid;
21700                     BackgroundThread.getHandler().post(new Runnable() {
21701                         @Override
21702                         public void run() {
21703                             revokeUriPermission(ActivityThread.currentActivityThread()
21704                                             .getApplicationThread(),
21705                                     null, DumpHeapActivity.JAVA_URI,
21706                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21707                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21708                                     UserHandle.myUserId());
21709                             ParcelFileDescriptor fd = null;
21710                             try {
21711                                 heapdumpFile.delete();
21712                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21713                                         ParcelFileDescriptor.MODE_CREATE |
21714                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21715                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21716                                                 ParcelFileDescriptor.MODE_APPEND);
21717                                 IApplicationThread thread = myProc.thread;
21718                                 if (thread != null) {
21719                                     try {
21720                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21721                                                 "Requesting dump heap from "
21722                                                 + myProc + " to " + heapdumpFile);
21723                                         thread.dumpHeap(/* managed= */ true,
21724                                                 /* mallocInfo= */ false, /* runGc= */ false,
21725                                                 heapdumpFile.toString(), fd);
21726                                     } catch (RemoteException e) {
21727                                     }
21728                                 }
21729                             } catch (FileNotFoundException e) {
21730                                 e.printStackTrace();
21731                             } finally {
21732                                 if (fd != null) {
21733                                     try {
21734                                         fd.close();
21735                                     } catch (IOException e) {
21736                                     }
21737                                 }
21738                             }
21739                         }
21740                     });
21741                 } else {
21742                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21743                             + ", but debugging not enabled");
21744                 }
21745             }
21746         }
21747     }
21748
21749     /**
21750      * Schedule PSS collection of a process.
21751      */
21752     void requestPssLocked(ProcessRecord proc, int procState) {
21753         if (mPendingPssProcesses.contains(proc)) {
21754             return;
21755         }
21756         if (mPendingPssProcesses.size() == 0) {
21757             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21758         }
21759         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21760         proc.pssProcState = procState;
21761         mPendingPssProcesses.add(proc);
21762     }
21763
21764     /**
21765      * Schedule PSS collection of all processes.
21766      */
21767     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21768         if (!always) {
21769             if (now < (mLastFullPssTime +
21770                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21771                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21772                 return;
21773             }
21774         }
21775         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21776         mLastFullPssTime = now;
21777         mFullPssPending = true;
21778         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21779         mPendingPssProcesses.clear();
21780         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21781             ProcessRecord app = mLruProcesses.get(i);
21782             if (app.thread == null
21783                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21784                 continue;
21785             }
21786             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21787                 app.pssProcState = app.setProcState;
21788                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21789                         mTestPssMode, isSleepingLocked(), now);
21790                 mPendingPssProcesses.add(app);
21791             }
21792         }
21793         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21794     }
21795
21796     public void setTestPssMode(boolean enabled) {
21797         synchronized (this) {
21798             mTestPssMode = enabled;
21799             if (enabled) {
21800                 // Whenever we enable the mode, we want to take a snapshot all of current
21801                 // process mem use.
21802                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21803             }
21804         }
21805     }
21806
21807     /**
21808      * Ask a given process to GC right now.
21809      */
21810     final void performAppGcLocked(ProcessRecord app) {
21811         try {
21812             app.lastRequestedGc = SystemClock.uptimeMillis();
21813             if (app.thread != null) {
21814                 if (app.reportLowMemory) {
21815                     app.reportLowMemory = false;
21816                     app.thread.scheduleLowMemory();
21817                 } else {
21818                     app.thread.processInBackground();
21819                 }
21820             }
21821         } catch (Exception e) {
21822             // whatever.
21823         }
21824     }
21825
21826     /**
21827      * Returns true if things are idle enough to perform GCs.
21828      */
21829     private final boolean canGcNowLocked() {
21830         boolean processingBroadcasts = false;
21831         for (BroadcastQueue q : mBroadcastQueues) {
21832             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21833                 processingBroadcasts = true;
21834             }
21835         }
21836         return !processingBroadcasts
21837                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21838     }
21839
21840     /**
21841      * Perform GCs on all processes that are waiting for it, but only
21842      * if things are idle.
21843      */
21844     final void performAppGcsLocked() {
21845         final int N = mProcessesToGc.size();
21846         if (N <= 0) {
21847             return;
21848         }
21849         if (canGcNowLocked()) {
21850             while (mProcessesToGc.size() > 0) {
21851                 ProcessRecord proc = mProcessesToGc.remove(0);
21852                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21853                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21854                             <= SystemClock.uptimeMillis()) {
21855                         // To avoid spamming the system, we will GC processes one
21856                         // at a time, waiting a few seconds between each.
21857                         performAppGcLocked(proc);
21858                         scheduleAppGcsLocked();
21859                         return;
21860                     } else {
21861                         // It hasn't been long enough since we last GCed this
21862                         // process...  put it in the list to wait for its time.
21863                         addProcessToGcListLocked(proc);
21864                         break;
21865                     }
21866                 }
21867             }
21868
21869             scheduleAppGcsLocked();
21870         }
21871     }
21872
21873     /**
21874      * If all looks good, perform GCs on all processes waiting for them.
21875      */
21876     final void performAppGcsIfAppropriateLocked() {
21877         if (canGcNowLocked()) {
21878             performAppGcsLocked();
21879             return;
21880         }
21881         // Still not idle, wait some more.
21882         scheduleAppGcsLocked();
21883     }
21884
21885     /**
21886      * Schedule the execution of all pending app GCs.
21887      */
21888     final void scheduleAppGcsLocked() {
21889         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21890
21891         if (mProcessesToGc.size() > 0) {
21892             // Schedule a GC for the time to the next process.
21893             ProcessRecord proc = mProcessesToGc.get(0);
21894             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21895
21896             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21897             long now = SystemClock.uptimeMillis();
21898             if (when < (now+mConstants.GC_TIMEOUT)) {
21899                 when = now + mConstants.GC_TIMEOUT;
21900             }
21901             mHandler.sendMessageAtTime(msg, when);
21902         }
21903     }
21904
21905     /**
21906      * Add a process to the array of processes waiting to be GCed.  Keeps the
21907      * list in sorted order by the last GC time.  The process can't already be
21908      * on the list.
21909      */
21910     final void addProcessToGcListLocked(ProcessRecord proc) {
21911         boolean added = false;
21912         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21913             if (mProcessesToGc.get(i).lastRequestedGc <
21914                     proc.lastRequestedGc) {
21915                 added = true;
21916                 mProcessesToGc.add(i+1, proc);
21917                 break;
21918             }
21919         }
21920         if (!added) {
21921             mProcessesToGc.add(0, proc);
21922         }
21923     }
21924
21925     /**
21926      * Set up to ask a process to GC itself.  This will either do it
21927      * immediately, or put it on the list of processes to gc the next
21928      * time things are idle.
21929      */
21930     final void scheduleAppGcLocked(ProcessRecord app) {
21931         long now = SystemClock.uptimeMillis();
21932         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21933             return;
21934         }
21935         if (!mProcessesToGc.contains(app)) {
21936             addProcessToGcListLocked(app);
21937             scheduleAppGcsLocked();
21938         }
21939     }
21940
21941     final void checkExcessivePowerUsageLocked() {
21942         updateCpuStatsNow();
21943
21944         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21945         boolean doCpuKills = true;
21946         if (mLastPowerCheckUptime == 0) {
21947             doCpuKills = false;
21948         }
21949         final long curUptime = SystemClock.uptimeMillis();
21950         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21951         mLastPowerCheckUptime = curUptime;
21952         int i = mLruProcesses.size();
21953         while (i > 0) {
21954             i--;
21955             ProcessRecord app = mLruProcesses.get(i);
21956             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21957                 if (app.lastCpuTime <= 0) {
21958                     continue;
21959                 }
21960                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21961                 if (DEBUG_POWER) {
21962                     StringBuilder sb = new StringBuilder(128);
21963                     sb.append("CPU for ");
21964                     app.toShortString(sb);
21965                     sb.append(": over ");
21966                     TimeUtils.formatDuration(uptimeSince, sb);
21967                     sb.append(" used ");
21968                     TimeUtils.formatDuration(cputimeUsed, sb);
21969                     sb.append(" (");
21970                     sb.append((cputimeUsed*100)/uptimeSince);
21971                     sb.append("%)");
21972                     Slog.i(TAG_POWER, sb.toString());
21973                 }
21974                 // If the process has used too much CPU over the last duration, the
21975                 // user probably doesn't want this, so kill!
21976                 if (doCpuKills && uptimeSince > 0) {
21977                     // What is the limit for this process?
21978                     int cpuLimit;
21979                     long checkDur = curUptime - app.whenUnimportant;
21980                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21981                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21982                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21983                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21984                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21985                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21986                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21987                     } else {
21988                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21989                     }
21990                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
21991                         synchronized (stats) {
21992                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
21993                                     uptimeSince, cputimeUsed);
21994                         }
21995                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
21996                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
21997                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
21998                     }
21999                 }
22000                 app.lastCpuTime = app.curCpuTime;
22001             }
22002         }
22003     }
22004
22005     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22006             long nowElapsed) {
22007         boolean success = true;
22008
22009         if (app.curRawAdj != app.setRawAdj) {
22010             app.setRawAdj = app.curRawAdj;
22011         }
22012
22013         int changes = 0;
22014
22015         if (app.curAdj != app.setAdj) {
22016             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22017             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22018                 String msg = "Set " + app.pid + " " + app.processName + " adj "
22019                         + app.curAdj + ": " + app.adjType;
22020                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22021             }
22022             app.setAdj = app.curAdj;
22023             app.verifiedAdj = ProcessList.INVALID_ADJ;
22024         }
22025
22026         if (app.setSchedGroup != app.curSchedGroup) {
22027             int oldSchedGroup = app.setSchedGroup;
22028             app.setSchedGroup = app.curSchedGroup;
22029             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22030                 String msg = "Setting sched group of " + app.processName
22031                         + " to " + app.curSchedGroup;
22032                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22033             }
22034             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22035                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22036                 app.kill(app.waitingToKill, true);
22037                 success = false;
22038             } else {
22039                 int processGroup;
22040                 switch (app.curSchedGroup) {
22041                     case ProcessList.SCHED_GROUP_BACKGROUND:
22042                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22043                         break;
22044                     case ProcessList.SCHED_GROUP_TOP_APP:
22045                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22046                         processGroup = THREAD_GROUP_TOP_APP;
22047                         break;
22048                     default:
22049                         processGroup = THREAD_GROUP_DEFAULT;
22050                         break;
22051                 }
22052                 long oldId = Binder.clearCallingIdentity();
22053                 try {
22054                     setProcessGroup(app.pid, processGroup);
22055                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22056                         // do nothing if we already switched to RT
22057                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22058                             mVrController.onTopProcChangedLocked(app);
22059                             if (mUseFifoUiScheduling) {
22060                                 // Switch UI pipeline for app to SCHED_FIFO
22061                                 app.savedPriority = Process.getThreadPriority(app.pid);
22062                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22063                                 if (app.renderThreadTid != 0) {
22064                                     scheduleAsFifoPriority(app.renderThreadTid,
22065                                         /* suppressLogs */true);
22066                                     if (DEBUG_OOM_ADJ) {
22067                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22068                                             app.renderThreadTid + ") to FIFO");
22069                                     }
22070                                 } else {
22071                                     if (DEBUG_OOM_ADJ) {
22072                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22073                                     }
22074                                 }
22075                             } else {
22076                                 // Boost priority for top app UI and render threads
22077                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22078                                 if (app.renderThreadTid != 0) {
22079                                     try {
22080                                         setThreadPriority(app.renderThreadTid,
22081                                                 TOP_APP_PRIORITY_BOOST);
22082                                     } catch (IllegalArgumentException e) {
22083                                         // thread died, ignore
22084                                     }
22085                                 }
22086                             }
22087                         }
22088                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22089                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22090                         mVrController.onTopProcChangedLocked(app);
22091                         if (mUseFifoUiScheduling) {
22092                             try {
22093                                 // Reset UI pipeline to SCHED_OTHER
22094                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22095                                 setThreadPriority(app.pid, app.savedPriority);
22096                                 if (app.renderThreadTid != 0) {
22097                                     setThreadScheduler(app.renderThreadTid,
22098                                         SCHED_OTHER, 0);
22099                                     setThreadPriority(app.renderThreadTid, -4);
22100                                 }
22101                             } catch (IllegalArgumentException e) {
22102                                 Slog.w(TAG,
22103                                         "Failed to set scheduling policy, thread does not exist:\n"
22104                                                 + e);
22105                             } catch (SecurityException e) {
22106                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22107                             }
22108                         } else {
22109                             // Reset priority for top app UI and render threads
22110                             setThreadPriority(app.pid, 0);
22111                             if (app.renderThreadTid != 0) {
22112                                 setThreadPriority(app.renderThreadTid, 0);
22113                             }
22114                         }
22115                     }
22116                 } catch (Exception e) {
22117                     if (false) {
22118                         Slog.w(TAG, "Failed setting process group of " + app.pid
22119                                 + " to " + app.curSchedGroup);
22120                         Slog.w(TAG, "at location", e);
22121                     }
22122                 } finally {
22123                     Binder.restoreCallingIdentity(oldId);
22124                 }
22125             }
22126         }
22127         if (app.repForegroundActivities != app.foregroundActivities) {
22128             app.repForegroundActivities = app.foregroundActivities;
22129             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22130         }
22131         if (app.repProcState != app.curProcState) {
22132             app.repProcState = app.curProcState;
22133             if (app.thread != null) {
22134                 try {
22135                     if (false) {
22136                         //RuntimeException h = new RuntimeException("here");
22137                         Slog.i(TAG, "Sending new process state " + app.repProcState
22138                                 + " to " + app /*, h*/);
22139                     }
22140                     app.thread.setProcessState(app.repProcState);
22141                 } catch (RemoteException e) {
22142                 }
22143             }
22144         }
22145         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22146                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22147             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22148                 // Experimental code to more aggressively collect pss while
22149                 // running test...  the problem is that this tends to collect
22150                 // the data right when a process is transitioning between process
22151                 // states, which well tend to give noisy data.
22152                 long start = SystemClock.uptimeMillis();
22153                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22154                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22155                 mPendingPssProcesses.remove(app);
22156                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22157                         + " to " + app.curProcState + ": "
22158                         + (SystemClock.uptimeMillis()-start) + "ms");
22159             }
22160             app.lastStateTime = now;
22161             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22162                     mTestPssMode, isSleepingLocked(), now);
22163             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22164                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22165                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22166                     + (app.nextPssTime-now) + ": " + app);
22167         } else {
22168             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22169                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22170                     mTestPssMode)))) {
22171                 requestPssLocked(app, app.setProcState);
22172                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22173                         mTestPssMode, isSleepingLocked(), now);
22174             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22175                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22176         }
22177         if (app.setProcState != app.curProcState) {
22178             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22179                 String msg = "Proc state change of " + app.processName
22180                         + " to " + app.curProcState;
22181                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22182             }
22183             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22184             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22185             if (setImportant && !curImportant) {
22186                 // This app is no longer something we consider important enough to allow to
22187                 // use arbitrary amounts of battery power.  Note
22188                 // its current CPU time to later know to kill it if
22189                 // it is not behaving well.
22190                 app.whenUnimportant = now;
22191                 app.lastCpuTime = 0;
22192             }
22193             // Inform UsageStats of important process state change
22194             // Must be called before updating setProcState
22195             maybeUpdateUsageStatsLocked(app, nowElapsed);
22196
22197             app.setProcState = app.curProcState;
22198             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22199                 app.notCachedSinceIdle = false;
22200             }
22201             if (!doingAll) {
22202                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22203             } else {
22204                 app.procStateChanged = true;
22205             }
22206         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22207                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22208             // For apps that sit around for a long time in the interactive state, we need
22209             // to report this at least once a day so they don't go idle.
22210             maybeUpdateUsageStatsLocked(app, nowElapsed);
22211         }
22212
22213         if (changes != 0) {
22214             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22215                     "Changes in " + app + ": " + changes);
22216             int i = mPendingProcessChanges.size()-1;
22217             ProcessChangeItem item = null;
22218             while (i >= 0) {
22219                 item = mPendingProcessChanges.get(i);
22220                 if (item.pid == app.pid) {
22221                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22222                             "Re-using existing item: " + item);
22223                     break;
22224                 }
22225                 i--;
22226             }
22227             if (i < 0) {
22228                 // No existing item in pending changes; need a new one.
22229                 final int NA = mAvailProcessChanges.size();
22230                 if (NA > 0) {
22231                     item = mAvailProcessChanges.remove(NA-1);
22232                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22233                             "Retrieving available item: " + item);
22234                 } else {
22235                     item = new ProcessChangeItem();
22236                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22237                             "Allocating new item: " + item);
22238                 }
22239                 item.changes = 0;
22240                 item.pid = app.pid;
22241                 item.uid = app.info.uid;
22242                 if (mPendingProcessChanges.size() == 0) {
22243                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22244                             "*** Enqueueing dispatch processes changed!");
22245                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22246                 }
22247                 mPendingProcessChanges.add(item);
22248             }
22249             item.changes |= changes;
22250             item.foregroundActivities = app.repForegroundActivities;
22251             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22252                     "Item " + Integer.toHexString(System.identityHashCode(item))
22253                     + " " + app.toShortString() + ": changes=" + item.changes
22254                     + " foreground=" + item.foregroundActivities
22255                     + " type=" + app.adjType + " source=" + app.adjSource
22256                     + " target=" + app.adjTarget);
22257         }
22258
22259         return success;
22260     }
22261
22262     private boolean isEphemeralLocked(int uid) {
22263         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22264         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22265             return false;
22266         }
22267         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22268                 packages[0]);
22269     }
22270
22271     @VisibleForTesting
22272     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22273         final UidRecord.ChangeItem pendingChange;
22274         if (uidRec == null || uidRec.pendingChange == null) {
22275             if (mPendingUidChanges.size() == 0) {
22276                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22277                         "*** Enqueueing dispatch uid changed!");
22278                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22279             }
22280             final int NA = mAvailUidChanges.size();
22281             if (NA > 0) {
22282                 pendingChange = mAvailUidChanges.remove(NA-1);
22283                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22284                         "Retrieving available item: " + pendingChange);
22285             } else {
22286                 pendingChange = new UidRecord.ChangeItem();
22287                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22288                         "Allocating new item: " + pendingChange);
22289             }
22290             if (uidRec != null) {
22291                 uidRec.pendingChange = pendingChange;
22292                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22293                     // If this uid is going away, and we haven't yet reported it is gone,
22294                     // then do so now.
22295                     change |= UidRecord.CHANGE_IDLE;
22296                 }
22297             } else if (uid < 0) {
22298                 throw new IllegalArgumentException("No UidRecord or uid");
22299             }
22300             pendingChange.uidRecord = uidRec;
22301             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22302             mPendingUidChanges.add(pendingChange);
22303         } else {
22304             pendingChange = uidRec.pendingChange;
22305             // If there is no change in idle or active state, then keep whatever was pending.
22306             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22307                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22308                         | UidRecord.CHANGE_ACTIVE));
22309             }
22310             // If there is no change in cached or uncached state, then keep whatever was pending.
22311             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22312                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22313                         | UidRecord.CHANGE_UNCACHED));
22314             }
22315             // If this is a report of the UID being gone, then we shouldn't keep any previous
22316             // report of it being active or cached.  (That is, a gone uid is never active,
22317             // and never cached.)
22318             if ((change & UidRecord.CHANGE_GONE) != 0) {
22319                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22320                 if (!uidRec.idle) {
22321                     // If this uid is going away, and we haven't yet reported it is gone,
22322                     // then do so now.
22323                     change |= UidRecord.CHANGE_IDLE;
22324                 }
22325             }
22326         }
22327         pendingChange.change = change;
22328         pendingChange.processState = uidRec != null
22329                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22330         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22331         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22332         if (uidRec != null) {
22333             uidRec.lastReportedChange = change;
22334             uidRec.updateLastDispatchedProcStateSeq(change);
22335         }
22336
22337         // Directly update the power manager, since we sit on top of it and it is critical
22338         // it be kept in sync (so wake locks will be held as soon as appropriate).
22339         if (mLocalPowerManager != null) {
22340             // TO DO: dispatch cached/uncached changes here, so we don't need to report
22341             // all proc state changes.
22342             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22343                 mLocalPowerManager.uidActive(pendingChange.uid);
22344             }
22345             if ((change & UidRecord.CHANGE_IDLE) != 0) {
22346                 mLocalPowerManager.uidIdle(pendingChange.uid);
22347             }
22348             if ((change & UidRecord.CHANGE_GONE) != 0) {
22349                 mLocalPowerManager.uidGone(pendingChange.uid);
22350             } else {
22351                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22352                         pendingChange.processState);
22353             }
22354         }
22355     }
22356
22357     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22358             String authority) {
22359         if (app == null) return;
22360         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22361             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22362             if (userState == null) return;
22363             final long now = SystemClock.elapsedRealtime();
22364             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22365             if (lastReported == null || lastReported < now - 60 * 1000L) {
22366                 if (mSystemReady) {
22367                     // Cannot touch the user stats if not system ready
22368                     mUsageStatsService.reportContentProviderUsage(
22369                             authority, providerPkgName, app.userId);
22370                 }
22371                 userState.mProviderLastReportedFg.put(authority, now);
22372             }
22373         }
22374     }
22375
22376     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22377         if (DEBUG_USAGE_STATS) {
22378             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22379                     + "] state changes: old = " + app.setProcState + ", new = "
22380                     + app.curProcState);
22381         }
22382         if (mUsageStatsService == null) {
22383             return;
22384         }
22385         boolean isInteraction;
22386         // To avoid some abuse patterns, we are going to be careful about what we consider
22387         // to be an app interaction.  Being the top activity doesn't count while the display
22388         // is sleeping, nor do short foreground services.
22389         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22390             isInteraction = true;
22391             app.fgInteractionTime = 0;
22392         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22393             if (app.fgInteractionTime == 0) {
22394                 app.fgInteractionTime = nowElapsed;
22395                 isInteraction = false;
22396             } else {
22397                 isInteraction = nowElapsed > app.fgInteractionTime
22398                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22399             }
22400         } else {
22401             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22402             app.fgInteractionTime = 0;
22403         }
22404         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22405                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22406             app.interactionEventTime = nowElapsed;
22407             String[] packages = app.getPackageList();
22408             if (packages != null) {
22409                 for (int i = 0; i < packages.length; i++) {
22410                     mUsageStatsService.reportEvent(packages[i], app.userId,
22411                             UsageEvents.Event.SYSTEM_INTERACTION);
22412                 }
22413             }
22414         }
22415         app.reportedInteraction = isInteraction;
22416         if (!isInteraction) {
22417             app.interactionEventTime = 0;
22418         }
22419     }
22420
22421     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22422         if (proc.thread != null) {
22423             if (proc.baseProcessTracker != null) {
22424                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22425             }
22426         }
22427     }
22428
22429     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22430             ProcessRecord TOP_APP, boolean doingAll, long now) {
22431         if (app.thread == null) {
22432             return false;
22433         }
22434
22435         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22436
22437         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22438     }
22439
22440     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22441             boolean oomAdj) {
22442         if (isForeground != proc.foregroundServices) {
22443             proc.foregroundServices = isForeground;
22444             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22445                     proc.info.uid);
22446             if (isForeground) {
22447                 if (curProcs == null) {
22448                     curProcs = new ArrayList<ProcessRecord>();
22449                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22450                 }
22451                 if (!curProcs.contains(proc)) {
22452                     curProcs.add(proc);
22453                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22454                             proc.info.packageName, proc.info.uid);
22455                 }
22456             } else {
22457                 if (curProcs != null) {
22458                     if (curProcs.remove(proc)) {
22459                         mBatteryStatsService.noteEvent(
22460                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22461                                 proc.info.packageName, proc.info.uid);
22462                         if (curProcs.size() <= 0) {
22463                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22464                         }
22465                     }
22466                 }
22467             }
22468             if (oomAdj) {
22469                 updateOomAdjLocked();
22470             }
22471         }
22472     }
22473
22474     private final ActivityRecord resumedAppLocked() {
22475         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22476         String pkg;
22477         int uid;
22478         if (act != null) {
22479             pkg = act.packageName;
22480             uid = act.info.applicationInfo.uid;
22481         } else {
22482             pkg = null;
22483             uid = -1;
22484         }
22485         // Has the UID or resumed package name changed?
22486         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22487                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22488             if (mCurResumedPackage != null) {
22489                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22490                         mCurResumedPackage, mCurResumedUid);
22491             }
22492             mCurResumedPackage = pkg;
22493             mCurResumedUid = uid;
22494             if (mCurResumedPackage != null) {
22495                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22496                         mCurResumedPackage, mCurResumedUid);
22497             }
22498         }
22499         return act;
22500     }
22501
22502     /**
22503      * Update OomAdj for a specific process.
22504      * @param app The process to update
22505      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22506      *                  if necessary, or skip.
22507      * @return whether updateOomAdjLocked(app) was successful.
22508      */
22509     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22510         final ActivityRecord TOP_ACT = resumedAppLocked();
22511         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22512         final boolean wasCached = app.cached;
22513
22514         mAdjSeq++;
22515
22516         // This is the desired cached adjusment we want to tell it to use.
22517         // If our app is currently cached, we know it, and that is it.  Otherwise,
22518         // we don't know it yet, and it needs to now be cached we will then
22519         // need to do a complete oom adj.
22520         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22521                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22522         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22523                 SystemClock.uptimeMillis());
22524         if (oomAdjAll
22525                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22526             // Changed to/from cached state, so apps after it in the LRU
22527             // list may also be changed.
22528             updateOomAdjLocked();
22529         }
22530         return success;
22531     }
22532
22533     final void updateOomAdjLocked() {
22534         final ActivityRecord TOP_ACT = resumedAppLocked();
22535         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22536         final long now = SystemClock.uptimeMillis();
22537         final long nowElapsed = SystemClock.elapsedRealtime();
22538         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22539         final int N = mLruProcesses.size();
22540
22541         if (false) {
22542             RuntimeException e = new RuntimeException();
22543             e.fillInStackTrace();
22544             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22545         }
22546
22547         // Reset state in all uid records.
22548         for (int i=mActiveUids.size()-1; i>=0; i--) {
22549             final UidRecord uidRec = mActiveUids.valueAt(i);
22550             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22551                     "Starting update of " + uidRec);
22552             uidRec.reset();
22553         }
22554
22555         mStackSupervisor.rankTaskLayersIfNeeded();
22556
22557         mAdjSeq++;
22558         mNewNumServiceProcs = 0;
22559         mNewNumAServiceProcs = 0;
22560
22561         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22562         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22563
22564         // Let's determine how many processes we have running vs.
22565         // how many slots we have for background processes; we may want
22566         // to put multiple processes in a slot of there are enough of
22567         // them.
22568         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22569                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22570         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22571         if (numEmptyProcs > cachedProcessLimit) {
22572             // If there are more empty processes than our limit on cached
22573             // processes, then use the cached process limit for the factor.
22574             // This ensures that the really old empty processes get pushed
22575             // down to the bottom, so if we are running low on memory we will
22576             // have a better chance at keeping around more cached processes
22577             // instead of a gazillion empty processes.
22578             numEmptyProcs = cachedProcessLimit;
22579         }
22580         int emptyFactor = numEmptyProcs/numSlots;
22581         if (emptyFactor < 1) emptyFactor = 1;
22582         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22583         if (cachedFactor < 1) cachedFactor = 1;
22584         int stepCached = 0;
22585         int stepEmpty = 0;
22586         int numCached = 0;
22587         int numEmpty = 0;
22588         int numTrimming = 0;
22589
22590         mNumNonCachedProcs = 0;
22591         mNumCachedHiddenProcs = 0;
22592
22593         // First update the OOM adjustment for each of the
22594         // application processes based on their current state.
22595         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22596         int nextCachedAdj = curCachedAdj+1;
22597         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22598         int nextEmptyAdj = curEmptyAdj+2;
22599         for (int i=N-1; i>=0; i--) {
22600             ProcessRecord app = mLruProcesses.get(i);
22601             if (!app.killedByAm && app.thread != null) {
22602                 app.procStateChanged = false;
22603                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22604
22605                 // If we haven't yet assigned the final cached adj
22606                 // to the process, do that now.
22607                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22608                     switch (app.curProcState) {
22609                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22610                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22611                             // This process is a cached process holding activities...
22612                             // assign it the next cached value for that type, and then
22613                             // step that cached level.
22614                             app.curRawAdj = curCachedAdj;
22615                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22616                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22617                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22618                                     + ")");
22619                             if (curCachedAdj != nextCachedAdj) {
22620                                 stepCached++;
22621                                 if (stepCached >= cachedFactor) {
22622                                     stepCached = 0;
22623                                     curCachedAdj = nextCachedAdj;
22624                                     nextCachedAdj += 2;
22625                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22626                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22627                                     }
22628                                 }
22629                             }
22630                             break;
22631                         default:
22632                             // For everything else, assign next empty cached process
22633                             // level and bump that up.  Note that this means that
22634                             // long-running services that have dropped down to the
22635                             // cached level will be treated as empty (since their process
22636                             // state is still as a service), which is what we want.
22637                             app.curRawAdj = curEmptyAdj;
22638                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22639                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22640                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22641                                     + ")");
22642                             if (curEmptyAdj != nextEmptyAdj) {
22643                                 stepEmpty++;
22644                                 if (stepEmpty >= emptyFactor) {
22645                                     stepEmpty = 0;
22646                                     curEmptyAdj = nextEmptyAdj;
22647                                     nextEmptyAdj += 2;
22648                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22649                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22650                                     }
22651                                 }
22652                             }
22653                             break;
22654                     }
22655                 }
22656
22657                 applyOomAdjLocked(app, true, now, nowElapsed);
22658
22659                 // Count the number of process types.
22660                 switch (app.curProcState) {
22661                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22662                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22663                         mNumCachedHiddenProcs++;
22664                         numCached++;
22665                         if (numCached > cachedProcessLimit) {
22666                             app.kill("cached #" + numCached, true);
22667                         }
22668                         break;
22669                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22670                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22671                                 && app.lastActivityTime < oldTime) {
22672                             app.kill("empty for "
22673                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22674                                     / 1000) + "s", true);
22675                         } else {
22676                             numEmpty++;
22677                             if (numEmpty > emptyProcessLimit) {
22678                                 app.kill("empty #" + numEmpty, true);
22679                             }
22680                         }
22681                         break;
22682                     default:
22683                         mNumNonCachedProcs++;
22684                         break;
22685                 }
22686
22687                 if (app.isolated && app.services.size() <= 0) {
22688                     // If this is an isolated process, and there are no
22689                     // services running in it, then the process is no longer
22690                     // needed.  We agressively kill these because we can by
22691                     // definition not re-use the same process again, and it is
22692                     // good to avoid having whatever code was running in them
22693                     // left sitting around after no longer needed.
22694                     app.kill("isolated not needed", true);
22695                 } else {
22696                     // Keeping this process, update its uid.
22697                     final UidRecord uidRec = app.uidRecord;
22698                     if (uidRec != null) {
22699                         uidRec.ephemeral = app.info.isInstantApp();
22700                         if (uidRec.curProcState > app.curProcState) {
22701                             uidRec.curProcState = app.curProcState;
22702                         }
22703                         if (app.foregroundServices) {
22704                             uidRec.foregroundServices = true;
22705                         }
22706                     }
22707                 }
22708
22709                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22710                         && !app.killedByAm) {
22711                     numTrimming++;
22712                 }
22713             }
22714         }
22715
22716         incrementProcStateSeqAndNotifyAppsLocked();
22717
22718         mNumServiceProcs = mNewNumServiceProcs;
22719
22720         // Now determine the memory trimming level of background processes.
22721         // Unfortunately we need to start at the back of the list to do this
22722         // properly.  We only do this if the number of background apps we
22723         // are managing to keep around is less than half the maximum we desire;
22724         // if we are keeping a good number around, we'll let them use whatever
22725         // memory they want.
22726         final int numCachedAndEmpty = numCached + numEmpty;
22727         int memFactor;
22728         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22729                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22730             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22731                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22732             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22733                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22734             } else {
22735                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22736             }
22737         } else {
22738             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22739         }
22740         // We always allow the memory level to go up (better).  We only allow it to go
22741         // down if we are in a state where that is allowed, *and* the total number of processes
22742         // has gone down since last time.
22743         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22744                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22745                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22746         if (memFactor > mLastMemoryLevel) {
22747             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22748                 memFactor = mLastMemoryLevel;
22749                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22750             }
22751         }
22752         if (memFactor != mLastMemoryLevel) {
22753             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22754         }
22755         mLastMemoryLevel = memFactor;
22756         mLastNumProcesses = mLruProcesses.size();
22757         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22758         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22759         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22760             if (mLowRamStartTime == 0) {
22761                 mLowRamStartTime = now;
22762             }
22763             int step = 0;
22764             int fgTrimLevel;
22765             switch (memFactor) {
22766                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22767                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22768                     break;
22769                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22770                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22771                     break;
22772                 default:
22773                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22774                     break;
22775             }
22776             int factor = numTrimming/3;
22777             int minFactor = 2;
22778             if (mHomeProcess != null) minFactor++;
22779             if (mPreviousProcess != null) minFactor++;
22780             if (factor < minFactor) factor = minFactor;
22781             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22782             for (int i=N-1; i>=0; i--) {
22783                 ProcessRecord app = mLruProcesses.get(i);
22784                 if (allChanged || app.procStateChanged) {
22785                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22786                     app.procStateChanged = false;
22787                 }
22788                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22789                         && !app.killedByAm) {
22790                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22791                         try {
22792                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22793                                     "Trimming memory of " + app.processName + " to " + curLevel);
22794                             app.thread.scheduleTrimMemory(curLevel);
22795                         } catch (RemoteException e) {
22796                         }
22797                         if (false) {
22798                             // For now we won't do this; our memory trimming seems
22799                             // to be good enough at this point that destroying
22800                             // activities causes more harm than good.
22801                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22802                                     && app != mHomeProcess && app != mPreviousProcess) {
22803                                 // Need to do this on its own message because the stack may not
22804                                 // be in a consistent state at this point.
22805                                 // For these apps we will also finish their activities
22806                                 // to help them free memory.
22807                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22808                             }
22809                         }
22810                     }
22811                     app.trimMemoryLevel = curLevel;
22812                     step++;
22813                     if (step >= factor) {
22814                         step = 0;
22815                         switch (curLevel) {
22816                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22817                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22818                                 break;
22819                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22820                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22821                                 break;
22822                         }
22823                     }
22824                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22825                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22826                             && app.thread != null) {
22827                         try {
22828                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22829                                     "Trimming memory of heavy-weight " + app.processName
22830                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22831                             app.thread.scheduleTrimMemory(
22832                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22833                         } catch (RemoteException e) {
22834                         }
22835                     }
22836                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22837                 } else {
22838                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22839                             || app.systemNoUi) && app.pendingUiClean) {
22840                         // If this application is now in the background and it
22841                         // had done UI, then give it the special trim level to
22842                         // have it free UI resources.
22843                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22844                         if (app.trimMemoryLevel < level && app.thread != null) {
22845                             try {
22846                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22847                                         "Trimming memory of bg-ui " + app.processName
22848                                         + " to " + level);
22849                                 app.thread.scheduleTrimMemory(level);
22850                             } catch (RemoteException e) {
22851                             }
22852                         }
22853                         app.pendingUiClean = false;
22854                     }
22855                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22856                         try {
22857                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22858                                     "Trimming memory of fg " + app.processName
22859                                     + " to " + fgTrimLevel);
22860                             app.thread.scheduleTrimMemory(fgTrimLevel);
22861                         } catch (RemoteException e) {
22862                         }
22863                     }
22864                     app.trimMemoryLevel = fgTrimLevel;
22865                 }
22866             }
22867         } else {
22868             if (mLowRamStartTime != 0) {
22869                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22870                 mLowRamStartTime = 0;
22871             }
22872             for (int i=N-1; i>=0; i--) {
22873                 ProcessRecord app = mLruProcesses.get(i);
22874                 if (allChanged || app.procStateChanged) {
22875                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22876                     app.procStateChanged = false;
22877                 }
22878                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22879                         || app.systemNoUi) && app.pendingUiClean) {
22880                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22881                             && app.thread != null) {
22882                         try {
22883                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22884                                     "Trimming memory of ui hidden " + app.processName
22885                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22886                             app.thread.scheduleTrimMemory(
22887                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22888                         } catch (RemoteException e) {
22889                         }
22890                     }
22891                     app.pendingUiClean = false;
22892                 }
22893                 app.trimMemoryLevel = 0;
22894             }
22895         }
22896
22897         if (mAlwaysFinishActivities) {
22898             // Need to do this on its own message because the stack may not
22899             // be in a consistent state at this point.
22900             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22901         }
22902
22903         if (allChanged) {
22904             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22905         }
22906
22907         ArrayList<UidRecord> becameIdle = null;
22908
22909         // Update from any uid changes.
22910         if (mLocalPowerManager != null) {
22911             mLocalPowerManager.startUidChanges();
22912         }
22913         for (int i=mActiveUids.size()-1; i>=0; i--) {
22914             final UidRecord uidRec = mActiveUids.valueAt(i);
22915             int uidChange = UidRecord.CHANGE_PROCSTATE;
22916             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22917                     && (uidRec.setProcState != uidRec.curProcState
22918                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
22919                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22920                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22921                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22922                         + " to " + uidRec.curWhitelist);
22923                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22924                         && !uidRec.curWhitelist) {
22925                     // UID is now in the background (and not on the temp whitelist).  Was it
22926                     // previously in the foreground (or on the temp whitelist)?
22927                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22928                             || uidRec.setWhitelist) {
22929                         uidRec.lastBackgroundTime = nowElapsed;
22930                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22931                             // Note: the background settle time is in elapsed realtime, while
22932                             // the handler time base is uptime.  All this means is that we may
22933                             // stop background uids later than we had intended, but that only
22934                             // happens because the device was sleeping so we are okay anyway.
22935                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22936                                     mConstants.BACKGROUND_SETTLE_TIME);
22937                         }
22938                     }
22939                     if (uidRec.idle && !uidRec.setIdle) {
22940                         uidChange = UidRecord.CHANGE_IDLE;
22941                         if (becameIdle == null) {
22942                             becameIdle = new ArrayList<>();
22943                         }
22944                         becameIdle.add(uidRec);
22945                     }
22946                 } else {
22947                     if (uidRec.idle) {
22948                         uidChange = UidRecord.CHANGE_ACTIVE;
22949                         EventLogTags.writeAmUidActive(uidRec.uid);
22950                         uidRec.idle = false;
22951                     }
22952                     uidRec.lastBackgroundTime = 0;
22953                 }
22954                 final boolean wasCached = uidRec.setProcState
22955                         > ActivityManager.PROCESS_STATE_RECEIVER;
22956                 final boolean isCached = uidRec.curProcState
22957                         > ActivityManager.PROCESS_STATE_RECEIVER;
22958                 if (wasCached != isCached ||
22959                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22960                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22961                 }
22962                 uidRec.setProcState = uidRec.curProcState;
22963                 uidRec.setWhitelist = uidRec.curWhitelist;
22964                 uidRec.setIdle = uidRec.idle;
22965                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22966                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22967                 if (uidRec.foregroundServices) {
22968                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22969                 }
22970             }
22971         }
22972         if (mLocalPowerManager != null) {
22973             mLocalPowerManager.finishUidChanges();
22974         }
22975
22976         if (becameIdle != null) {
22977             // If we have any new uids that became idle this time, we need to make sure
22978             // they aren't left with running services.
22979             for (int i = becameIdle.size() - 1; i >= 0; i--) {
22980                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22981             }
22982         }
22983
22984         if (mProcessStats.shouldWriteNowLocked(now)) {
22985             mHandler.post(new Runnable() {
22986                 @Override public void run() {
22987                     synchronized (ActivityManagerService.this) {
22988                         mProcessStats.writeStateAsyncLocked();
22989                     }
22990                 }
22991             });
22992         }
22993
22994         if (DEBUG_OOM_ADJ) {
22995             final long duration = SystemClock.uptimeMillis() - now;
22996             if (false) {
22997                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
22998                         new RuntimeException("here").fillInStackTrace());
22999             } else {
23000                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23001             }
23002         }
23003     }
23004
23005     @Override
23006     public void makePackageIdle(String packageName, int userId) {
23007         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23008                 != PackageManager.PERMISSION_GRANTED) {
23009             String msg = "Permission Denial: makePackageIdle() from pid="
23010                     + Binder.getCallingPid()
23011                     + ", uid=" + Binder.getCallingUid()
23012                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23013             Slog.w(TAG, msg);
23014             throw new SecurityException(msg);
23015         }
23016         final int callingPid = Binder.getCallingPid();
23017         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23018                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23019         long callingId = Binder.clearCallingIdentity();
23020         synchronized(this) {
23021             try {
23022                 IPackageManager pm = AppGlobals.getPackageManager();
23023                 int pkgUid = -1;
23024                 try {
23025                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23026                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23027                 } catch (RemoteException e) {
23028                 }
23029                 if (pkgUid == -1) {
23030                     throw new IllegalArgumentException("Unknown package name " + packageName);
23031                 }
23032
23033                 if (mLocalPowerManager != null) {
23034                     mLocalPowerManager.startUidChanges();
23035                 }
23036                 final int appId = UserHandle.getAppId(pkgUid);
23037                 final int N = mActiveUids.size();
23038                 for (int i=N-1; i>=0; i--) {
23039                     final UidRecord uidRec = mActiveUids.valueAt(i);
23040                     final long bgTime = uidRec.lastBackgroundTime;
23041                     if (bgTime > 0 && !uidRec.idle) {
23042                         if (UserHandle.getAppId(uidRec.uid) == appId) {
23043                             if (userId == UserHandle.USER_ALL ||
23044                                     userId == UserHandle.getUserId(uidRec.uid)) {
23045                                 EventLogTags.writeAmUidIdle(uidRec.uid);
23046                                 uidRec.idle = true;
23047                                 uidRec.setIdle = true;
23048                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23049                                         + " from package " + packageName + " user " + userId);
23050                                 doStopUidLocked(uidRec.uid, uidRec);
23051                             }
23052                         }
23053                     }
23054                 }
23055             } finally {
23056                 if (mLocalPowerManager != null) {
23057                     mLocalPowerManager.finishUidChanges();
23058                 }
23059                 Binder.restoreCallingIdentity(callingId);
23060             }
23061         }
23062     }
23063
23064     final void idleUids() {
23065         synchronized (this) {
23066             final int N = mActiveUids.size();
23067             if (N <= 0) {
23068                 return;
23069             }
23070             final long nowElapsed = SystemClock.elapsedRealtime();
23071             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23072             long nextTime = 0;
23073             if (mLocalPowerManager != null) {
23074                 mLocalPowerManager.startUidChanges();
23075             }
23076             for (int i=N-1; i>=0; i--) {
23077                 final UidRecord uidRec = mActiveUids.valueAt(i);
23078                 final long bgTime = uidRec.lastBackgroundTime;
23079                 if (bgTime > 0 && !uidRec.idle) {
23080                     if (bgTime <= maxBgTime) {
23081                         EventLogTags.writeAmUidIdle(uidRec.uid);
23082                         uidRec.idle = true;
23083                         uidRec.setIdle = true;
23084                         doStopUidLocked(uidRec.uid, uidRec);
23085                     } else {
23086                         if (nextTime == 0 || nextTime > bgTime) {
23087                             nextTime = bgTime;
23088                         }
23089                     }
23090                 }
23091             }
23092             if (mLocalPowerManager != null) {
23093                 mLocalPowerManager.finishUidChanges();
23094             }
23095             if (nextTime > 0) {
23096                 mHandler.removeMessages(IDLE_UIDS_MSG);
23097                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23098                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23099             }
23100         }
23101     }
23102
23103     /**
23104      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23105      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23106      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23107      */
23108     @VisibleForTesting
23109     @GuardedBy("this")
23110     void incrementProcStateSeqAndNotifyAppsLocked() {
23111         if (mWaitForNetworkTimeoutMs <= 0) {
23112             return;
23113         }
23114         // Used for identifying which uids need to block for network.
23115         ArrayList<Integer> blockingUids = null;
23116         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23117             final UidRecord uidRec = mActiveUids.valueAt(i);
23118             // If the network is not restricted for uid, then nothing to do here.
23119             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23120                 continue;
23121             }
23122             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23123                 continue;
23124             }
23125             // If process state is not changed, then there's nothing to do.
23126             if (uidRec.setProcState == uidRec.curProcState) {
23127                 continue;
23128             }
23129             final int blockState = getBlockStateForUid(uidRec);
23130             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23131             // there's nothing the app needs to do in this scenario.
23132             if (blockState == NETWORK_STATE_NO_CHANGE) {
23133                 continue;
23134             }
23135             synchronized (uidRec.networkStateLock) {
23136                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23137                 if (blockState == NETWORK_STATE_BLOCK) {
23138                     if (blockingUids == null) {
23139                         blockingUids = new ArrayList<>();
23140                     }
23141                     blockingUids.add(uidRec.uid);
23142                 } else {
23143                     if (DEBUG_NETWORK) {
23144                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23145                                 + " threads for uid: " + uidRec);
23146                     }
23147                     if (uidRec.waitingForNetwork) {
23148                         uidRec.networkStateLock.notifyAll();
23149                     }
23150                 }
23151             }
23152         }
23153
23154         // There are no uids that need to block, so nothing more to do.
23155         if (blockingUids == null) {
23156             return;
23157         }
23158
23159         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23160             final ProcessRecord app = mLruProcesses.get(i);
23161             if (!blockingUids.contains(app.uid)) {
23162                 continue;
23163             }
23164             if (!app.killedByAm && app.thread != null) {
23165                 final UidRecord uidRec = mActiveUids.get(app.uid);
23166                 try {
23167                     if (DEBUG_NETWORK) {
23168                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23169                                 + uidRec);
23170                     }
23171                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23172                 } catch (RemoteException ignored) {
23173                 }
23174             }
23175         }
23176     }
23177
23178     /**
23179      * Checks if the uid is coming from background to foreground or vice versa and returns
23180      * appropriate block state based on this.
23181      *
23182      * @return blockState based on whether the uid is coming from background to foreground or
23183      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23184      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23185      *         {@link #NETWORK_STATE_NO_CHANGE}.
23186      */
23187     @VisibleForTesting
23188     int getBlockStateForUid(UidRecord uidRec) {
23189         // Denotes whether uid's process state is currently allowed network access.
23190         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23191                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23192         // Denotes whether uid's process state was previously allowed network access.
23193         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23194                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23195
23196         // When the uid is coming to foreground, AMS should inform the app thread that it should
23197         // block for the network rules to get updated before launching an activity.
23198         if (!wasAllowed && isAllowed) {
23199             return NETWORK_STATE_BLOCK;
23200         }
23201         // When the uid is going to background, AMS should inform the app thread that if an
23202         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23203         if (wasAllowed && !isAllowed) {
23204             return NETWORK_STATE_UNBLOCK;
23205         }
23206         return NETWORK_STATE_NO_CHANGE;
23207     }
23208
23209     final void runInBackgroundDisabled(int uid) {
23210         synchronized (this) {
23211             UidRecord uidRec = mActiveUids.get(uid);
23212             if (uidRec != null) {
23213                 // This uid is actually running...  should it be considered background now?
23214                 if (uidRec.idle) {
23215                     doStopUidLocked(uidRec.uid, uidRec);
23216                 }
23217             } else {
23218                 // This uid isn't actually running...  still send a report about it being "stopped".
23219                 doStopUidLocked(uid, null);
23220             }
23221         }
23222     }
23223
23224     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23225         mServices.stopInBackgroundLocked(uid);
23226         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23227     }
23228
23229     /**
23230      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23231      */
23232     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23233             long duration, String tag) {
23234         if (DEBUG_WHITELISTS) {
23235             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23236                     + targetUid + ", " + duration + ")");
23237         }
23238
23239         synchronized (mPidsSelfLocked) {
23240             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23241             if (pr == null) {
23242                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23243                         + callerPid);
23244                 return;
23245             }
23246             if (!pr.whitelistManager) {
23247                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23248                         != PackageManager.PERMISSION_GRANTED) {
23249                     if (DEBUG_WHITELISTS) {
23250                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23251                                 + ": pid " + callerPid + " is not allowed");
23252                     }
23253                     return;
23254                 }
23255             }
23256         }
23257
23258         tempWhitelistUidLocked(targetUid, duration, tag);
23259     }
23260
23261     /**
23262      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23263      */
23264     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23265         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23266         setUidTempWhitelistStateLocked(targetUid, true);
23267         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23268     }
23269
23270     void pushTempWhitelist() {
23271         final int N;
23272         final PendingTempWhitelist[] list;
23273
23274         // First copy out the pending changes...  we need to leave them in the map for now,
23275         // in case someone needs to check what is coming up while we don't have the lock held.
23276         synchronized(this) {
23277             N = mPendingTempWhitelist.size();
23278             list = new PendingTempWhitelist[N];
23279             for (int i = 0; i < N; i++) {
23280                 list[i] = mPendingTempWhitelist.valueAt(i);
23281             }
23282         }
23283
23284         // Now safely dispatch changes to device idle controller.
23285         for (int i = 0; i < N; i++) {
23286             PendingTempWhitelist ptw = list[i];
23287             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23288                     ptw.duration, true, ptw.tag);
23289         }
23290
23291         // And now we can safely remove them from the map.
23292         synchronized(this) {
23293             for (int i = 0; i < N; i++) {
23294                 PendingTempWhitelist ptw = list[i];
23295                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23296                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23297                     mPendingTempWhitelist.removeAt(index);
23298                 }
23299             }
23300         }
23301     }
23302
23303     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23304         boolean changed = false;
23305         for (int i=mActiveUids.size()-1; i>=0; i--) {
23306             final UidRecord uidRec = mActiveUids.valueAt(i);
23307             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23308                 uidRec.curWhitelist = onWhitelist;
23309                 changed = true;
23310             }
23311         }
23312         if (changed) {
23313             updateOomAdjLocked();
23314         }
23315     }
23316
23317     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23318         boolean changed = false;
23319         final UidRecord uidRec = mActiveUids.get(uid);
23320         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23321             uidRec.curWhitelist = onWhitelist;
23322             updateOomAdjLocked();
23323         }
23324     }
23325
23326     final void trimApplications() {
23327         synchronized (this) {
23328             int i;
23329
23330             // First remove any unused application processes whose package
23331             // has been removed.
23332             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23333                 final ProcessRecord app = mRemovedProcesses.get(i);
23334                 if (app.activities.size() == 0
23335                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23336                     Slog.i(
23337                         TAG, "Exiting empty application process "
23338                         + app.toShortString() + " ("
23339                         + (app.thread != null ? app.thread.asBinder() : null)
23340                         + ")\n");
23341                     if (app.pid > 0 && app.pid != MY_PID) {
23342                         app.kill("empty", false);
23343                     } else {
23344                         try {
23345                             app.thread.scheduleExit();
23346                         } catch (Exception e) {
23347                             // Ignore exceptions.
23348                         }
23349                     }
23350                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23351                     mRemovedProcesses.remove(i);
23352
23353                     if (app.persistent) {
23354                         addAppLocked(app.info, null, false, null /* ABI override */);
23355                     }
23356                 }
23357             }
23358
23359             // Now update the oom adj for all processes.
23360             updateOomAdjLocked();
23361         }
23362     }
23363
23364     /** This method sends the specified signal to each of the persistent apps */
23365     public void signalPersistentProcesses(int sig) throws RemoteException {
23366         if (sig != SIGNAL_USR1) {
23367             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23368         }
23369
23370         synchronized (this) {
23371             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23372                     != PackageManager.PERMISSION_GRANTED) {
23373                 throw new SecurityException("Requires permission "
23374                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23375             }
23376
23377             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23378                 ProcessRecord r = mLruProcesses.get(i);
23379                 if (r.thread != null && r.persistent) {
23380                     sendSignal(r.pid, sig);
23381                 }
23382             }
23383         }
23384     }
23385
23386     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23387         if (proc == null || proc == mProfileProc) {
23388             proc = mProfileProc;
23389             profileType = mProfileType;
23390             clearProfilerLocked();
23391         }
23392         if (proc == null) {
23393             return;
23394         }
23395         try {
23396             proc.thread.profilerControl(false, null, profileType);
23397         } catch (RemoteException e) {
23398             throw new IllegalStateException("Process disappeared");
23399         }
23400     }
23401
23402     private void clearProfilerLocked() {
23403         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23404             try {
23405                 mProfilerInfo.profileFd.close();
23406             } catch (IOException e) {
23407             }
23408         }
23409         mProfileApp = null;
23410         mProfileProc = null;
23411         mProfilerInfo = null;
23412     }
23413
23414     public boolean profileControl(String process, int userId, boolean start,
23415             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23416
23417         try {
23418             synchronized (this) {
23419                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23420                 // its own permission.
23421                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23422                         != PackageManager.PERMISSION_GRANTED) {
23423                     throw new SecurityException("Requires permission "
23424                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23425                 }
23426
23427                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23428                     throw new IllegalArgumentException("null profile info or fd");
23429                 }
23430
23431                 ProcessRecord proc = null;
23432                 if (process != null) {
23433                     proc = findProcessLocked(process, userId, "profileControl");
23434                 }
23435
23436                 if (start && (proc == null || proc.thread == null)) {
23437                     throw new IllegalArgumentException("Unknown process: " + process);
23438                 }
23439
23440                 if (start) {
23441                     stopProfilerLocked(null, 0);
23442                     setProfileApp(proc.info, proc.processName, profilerInfo);
23443                     mProfileProc = proc;
23444                     mProfileType = profileType;
23445                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23446                     try {
23447                         fd = fd.dup();
23448                     } catch (IOException e) {
23449                         fd = null;
23450                     }
23451                     profilerInfo.profileFd = fd;
23452                     proc.thread.profilerControl(start, profilerInfo, profileType);
23453                     fd = null;
23454                     try {
23455                         mProfilerInfo.profileFd.close();
23456                     } catch (IOException e) {
23457                     }
23458                     mProfilerInfo.profileFd = null;
23459                 } else {
23460                     stopProfilerLocked(proc, profileType);
23461                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23462                         try {
23463                             profilerInfo.profileFd.close();
23464                         } catch (IOException e) {
23465                         }
23466                     }
23467                 }
23468
23469                 return true;
23470             }
23471         } catch (RemoteException e) {
23472             throw new IllegalStateException("Process disappeared");
23473         } finally {
23474             if (profilerInfo != null && profilerInfo.profileFd != null) {
23475                 try {
23476                     profilerInfo.profileFd.close();
23477                 } catch (IOException e) {
23478                 }
23479             }
23480         }
23481     }
23482
23483     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23484         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23485                 userId, true, ALLOW_FULL_ONLY, callName, null);
23486         ProcessRecord proc = null;
23487         try {
23488             int pid = Integer.parseInt(process);
23489             synchronized (mPidsSelfLocked) {
23490                 proc = mPidsSelfLocked.get(pid);
23491             }
23492         } catch (NumberFormatException e) {
23493         }
23494
23495         if (proc == null) {
23496             ArrayMap<String, SparseArray<ProcessRecord>> all
23497                     = mProcessNames.getMap();
23498             SparseArray<ProcessRecord> procs = all.get(process);
23499             if (procs != null && procs.size() > 0) {
23500                 proc = procs.valueAt(0);
23501                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23502                     for (int i=1; i<procs.size(); i++) {
23503                         ProcessRecord thisProc = procs.valueAt(i);
23504                         if (thisProc.userId == userId) {
23505                             proc = thisProc;
23506                             break;
23507                         }
23508                     }
23509                 }
23510             }
23511         }
23512
23513         return proc;
23514     }
23515
23516     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23517             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23518
23519         try {
23520             synchronized (this) {
23521                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23522                 // its own permission (same as profileControl).
23523                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23524                         != PackageManager.PERMISSION_GRANTED) {
23525                     throw new SecurityException("Requires permission "
23526                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23527                 }
23528
23529                 if (fd == null) {
23530                     throw new IllegalArgumentException("null fd");
23531                 }
23532
23533                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23534                 if (proc == null || proc.thread == null) {
23535                     throw new IllegalArgumentException("Unknown process: " + process);
23536                 }
23537
23538                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23539                 if (!isDebuggable) {
23540                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23541                         throw new SecurityException("Process not debuggable: " + proc);
23542                     }
23543                 }
23544
23545                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23546                 fd = null;
23547                 return true;
23548             }
23549         } catch (RemoteException e) {
23550             throw new IllegalStateException("Process disappeared");
23551         } finally {
23552             if (fd != null) {
23553                 try {
23554                     fd.close();
23555                 } catch (IOException e) {
23556                 }
23557             }
23558         }
23559     }
23560
23561     @Override
23562     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23563             String reportPackage) {
23564         if (processName != null) {
23565             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23566                     "setDumpHeapDebugLimit()");
23567         } else {
23568             synchronized (mPidsSelfLocked) {
23569                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23570                 if (proc == null) {
23571                     throw new SecurityException("No process found for calling pid "
23572                             + Binder.getCallingPid());
23573                 }
23574                 if (!Build.IS_DEBUGGABLE
23575                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23576                     throw new SecurityException("Not running a debuggable build");
23577                 }
23578                 processName = proc.processName;
23579                 uid = proc.uid;
23580                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23581                     throw new SecurityException("Package " + reportPackage + " is not running in "
23582                             + proc);
23583                 }
23584             }
23585         }
23586         synchronized (this) {
23587             if (maxMemSize > 0) {
23588                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23589             } else {
23590                 if (uid != 0) {
23591                     mMemWatchProcesses.remove(processName, uid);
23592                 } else {
23593                     mMemWatchProcesses.getMap().remove(processName);
23594                 }
23595             }
23596         }
23597     }
23598
23599     @Override
23600     public void dumpHeapFinished(String path) {
23601         synchronized (this) {
23602             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23603                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23604                         + " does not match last pid " + mMemWatchDumpPid);
23605                 return;
23606             }
23607             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23608                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23609                         + " does not match last path " + mMemWatchDumpFile);
23610                 return;
23611             }
23612             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23613             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23614
23615             // Forced gc to clean up the remnant hprof fd.
23616             Runtime.getRuntime().gc();
23617         }
23618     }
23619
23620     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23621     public void monitor() {
23622         synchronized (this) { }
23623     }
23624
23625     void onCoreSettingsChange(Bundle settings) {
23626         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23627             ProcessRecord processRecord = mLruProcesses.get(i);
23628             try {
23629                 if (processRecord.thread != null) {
23630                     processRecord.thread.setCoreSettings(settings);
23631                 }
23632             } catch (RemoteException re) {
23633                 /* ignore */
23634             }
23635         }
23636     }
23637
23638     // Multi-user methods
23639
23640     /**
23641      * Start user, if its not already running, but don't bring it to foreground.
23642      */
23643     @Override
23644     public boolean startUserInBackground(final int userId) {
23645         return mUserController.startUser(userId, /* foreground */ false);
23646     }
23647
23648     @Override
23649     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23650         return mUserController.unlockUser(userId, token, secret, listener);
23651     }
23652
23653     @Override
23654     public boolean switchUser(final int targetUserId) {
23655         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23656         int currentUserId;
23657         UserInfo targetUserInfo;
23658         synchronized (this) {
23659             currentUserId = mUserController.getCurrentUserIdLocked();
23660             targetUserInfo = mUserController.getUserInfo(targetUserId);
23661             if (targetUserId == currentUserId) {
23662                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23663                 return true;
23664             }
23665             if (targetUserInfo == null) {
23666                 Slog.w(TAG, "No user info for user #" + targetUserId);
23667                 return false;
23668             }
23669             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23670                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23671                         + " when device is in demo mode");
23672                 return false;
23673             }
23674             if (!targetUserInfo.supportsSwitchTo()) {
23675                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23676                 return false;
23677             }
23678             if (targetUserInfo.isManagedProfile()) {
23679                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23680                 return false;
23681             }
23682             mUserController.setTargetUserIdLocked(targetUserId);
23683         }
23684         if (mUserController.mUserSwitchUiEnabled) {
23685             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23686             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23687             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23688             mUiHandler.sendMessage(mHandler.obtainMessage(
23689                     START_USER_SWITCH_UI_MSG, userNames));
23690         } else {
23691             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23692             mHandler.sendMessage(mHandler.obtainMessage(
23693                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23694         }
23695         return true;
23696     }
23697
23698     void scheduleStartProfilesLocked() {
23699         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23700             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23701                     DateUtils.SECOND_IN_MILLIS);
23702         }
23703     }
23704
23705     @Override
23706     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23707         return mUserController.stopUser(userId, force, callback);
23708     }
23709
23710     @Override
23711     public UserInfo getCurrentUser() {
23712         return mUserController.getCurrentUser();
23713     }
23714
23715     String getStartedUserState(int userId) {
23716         synchronized (this) {
23717             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23718             return UserState.stateToString(userState.state);
23719         }
23720     }
23721
23722     @Override
23723     public boolean isUserRunning(int userId, int flags) {
23724         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23725                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23726                     != PackageManager.PERMISSION_GRANTED) {
23727             String msg = "Permission Denial: isUserRunning() from pid="
23728                     + Binder.getCallingPid()
23729                     + ", uid=" + Binder.getCallingUid()
23730                     + " requires " + INTERACT_ACROSS_USERS;
23731             Slog.w(TAG, msg);
23732             throw new SecurityException(msg);
23733         }
23734         synchronized (this) {
23735             return mUserController.isUserRunningLocked(userId, flags);
23736         }
23737     }
23738
23739     @Override
23740     public int[] getRunningUserIds() {
23741         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23742                 != PackageManager.PERMISSION_GRANTED) {
23743             String msg = "Permission Denial: isUserRunning() from pid="
23744                     + Binder.getCallingPid()
23745                     + ", uid=" + Binder.getCallingUid()
23746                     + " requires " + INTERACT_ACROSS_USERS;
23747             Slog.w(TAG, msg);
23748             throw new SecurityException(msg);
23749         }
23750         synchronized (this) {
23751             return mUserController.getStartedUserArrayLocked();
23752         }
23753     }
23754
23755     @Override
23756     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23757         mUserController.registerUserSwitchObserver(observer, name);
23758     }
23759
23760     @Override
23761     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23762         mUserController.unregisterUserSwitchObserver(observer);
23763     }
23764
23765     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23766         if (info == null) return null;
23767         ApplicationInfo newInfo = new ApplicationInfo(info);
23768         newInfo.initForUser(userId);
23769         return newInfo;
23770     }
23771
23772     public boolean isUserStopped(int userId) {
23773         synchronized (this) {
23774             return mUserController.getStartedUserStateLocked(userId) == null;
23775         }
23776     }
23777
23778     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23779         if (aInfo == null
23780                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23781             return aInfo;
23782         }
23783
23784         ActivityInfo info = new ActivityInfo(aInfo);
23785         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23786         return info;
23787     }
23788
23789     private boolean processSanityChecksLocked(ProcessRecord process) {
23790         if (process == null || process.thread == null) {
23791             return false;
23792         }
23793
23794         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23795         if (!isDebuggable) {
23796             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23797                 return false;
23798             }
23799         }
23800
23801         return true;
23802     }
23803
23804     public boolean startBinderTracking() throws RemoteException {
23805         synchronized (this) {
23806             mBinderTransactionTrackingEnabled = true;
23807             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23808             // permission (same as profileControl).
23809             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23810                     != PackageManager.PERMISSION_GRANTED) {
23811                 throw new SecurityException("Requires permission "
23812                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23813             }
23814
23815             for (int i = 0; i < mLruProcesses.size(); i++) {
23816                 ProcessRecord process = mLruProcesses.get(i);
23817                 if (!processSanityChecksLocked(process)) {
23818                     continue;
23819                 }
23820                 try {
23821                     process.thread.startBinderTracking();
23822                 } catch (RemoteException e) {
23823                     Log.v(TAG, "Process disappared");
23824                 }
23825             }
23826             return true;
23827         }
23828     }
23829
23830     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23831         try {
23832             synchronized (this) {
23833                 mBinderTransactionTrackingEnabled = false;
23834                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23835                 // permission (same as profileControl).
23836                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23837                         != PackageManager.PERMISSION_GRANTED) {
23838                     throw new SecurityException("Requires permission "
23839                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23840                 }
23841
23842                 if (fd == null) {
23843                     throw new IllegalArgumentException("null fd");
23844                 }
23845
23846                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23847                 pw.println("Binder transaction traces for all processes.\n");
23848                 for (ProcessRecord process : mLruProcesses) {
23849                     if (!processSanityChecksLocked(process)) {
23850                         continue;
23851                     }
23852
23853                     pw.println("Traces for process: " + process.processName);
23854                     pw.flush();
23855                     try {
23856                         TransferPipe tp = new TransferPipe();
23857                         try {
23858                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23859                             tp.go(fd.getFileDescriptor());
23860                         } finally {
23861                             tp.kill();
23862                         }
23863                     } catch (IOException e) {
23864                         pw.println("Failure while dumping IPC traces from " + process +
23865                                 ".  Exception: " + e);
23866                         pw.flush();
23867                     } catch (RemoteException e) {
23868                         pw.println("Got a RemoteException while dumping IPC traces from " +
23869                                 process + ".  Exception: " + e);
23870                         pw.flush();
23871                     }
23872                 }
23873                 fd = null;
23874                 return true;
23875             }
23876         } finally {
23877             if (fd != null) {
23878                 try {
23879                     fd.close();
23880                 } catch (IOException e) {
23881                 }
23882             }
23883         }
23884     }
23885
23886     @VisibleForTesting
23887     final class LocalService extends ActivityManagerInternal {
23888         @Override
23889         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23890                 int targetUserId) {
23891             synchronized (ActivityManagerService.this) {
23892                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23893                         targetPkg, intent, null, targetUserId);
23894             }
23895         }
23896
23897         @Override
23898         public String checkContentProviderAccess(String authority, int userId) {
23899             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23900         }
23901
23902         @Override
23903         public void onWakefulnessChanged(int wakefulness) {
23904             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23905         }
23906
23907         @Override
23908         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23909                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23910             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23911                     processName, abiOverride, uid, crashHandler);
23912         }
23913
23914         @Override
23915         public SleepToken acquireSleepToken(String tag, int displayId) {
23916             Preconditions.checkNotNull(tag);
23917             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23918         }
23919
23920         @Override
23921         public ComponentName getHomeActivityForUser(int userId) {
23922             synchronized (ActivityManagerService.this) {
23923                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23924                 return homeActivity == null ? null : homeActivity.realActivity;
23925             }
23926         }
23927
23928         @Override
23929         public void onUserRemoved(int userId) {
23930             synchronized (ActivityManagerService.this) {
23931                 ActivityManagerService.this.onUserStoppedLocked(userId);
23932             }
23933             mBatteryStatsService.onUserRemoved(userId);
23934         }
23935
23936         @Override
23937         public void onLocalVoiceInteractionStarted(IBinder activity,
23938                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23939             synchronized (ActivityManagerService.this) {
23940                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23941                         voiceSession, voiceInteractor);
23942             }
23943         }
23944
23945         @Override
23946         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23947             synchronized (ActivityManagerService.this) {
23948                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23949                         reasons, timestamp);
23950             }
23951         }
23952
23953         @Override
23954         public void notifyAppTransitionFinished() {
23955             synchronized (ActivityManagerService.this) {
23956                 mStackSupervisor.notifyAppTransitionDone();
23957             }
23958         }
23959
23960         @Override
23961         public void notifyAppTransitionCancelled() {
23962             synchronized (ActivityManagerService.this) {
23963                 mStackSupervisor.notifyAppTransitionDone();
23964             }
23965         }
23966
23967         @Override
23968         public List<IBinder> getTopVisibleActivities() {
23969             synchronized (ActivityManagerService.this) {
23970                 return mStackSupervisor.getTopVisibleActivities();
23971             }
23972         }
23973
23974         @Override
23975         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23976             synchronized (ActivityManagerService.this) {
23977                 mStackSupervisor.setDockedStackMinimized(minimized);
23978             }
23979         }
23980
23981         @Override
23982         public void killForegroundAppsForUser(int userHandle) {
23983             synchronized (ActivityManagerService.this) {
23984                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23985                 final int NP = mProcessNames.getMap().size();
23986                 for (int ip = 0; ip < NP; ip++) {
23987                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23988                     final int NA = apps.size();
23989                     for (int ia = 0; ia < NA; ia++) {
23990                         final ProcessRecord app = apps.valueAt(ia);
23991                         if (app.persistent) {
23992                             // We don't kill persistent processes.
23993                             continue;
23994                         }
23995                         if (app.removed) {
23996                             procs.add(app);
23997                         } else if (app.userId == userHandle && app.foregroundActivities) {
23998                             app.removed = true;
23999                             procs.add(app);
24000                         }
24001                     }
24002                 }
24003
24004                 final int N = procs.size();
24005                 for (int i = 0; i < N; i++) {
24006                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
24007                 }
24008             }
24009         }
24010
24011         @Override
24012         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24013                 long duration) {
24014             if (!(target instanceof PendingIntentRecord)) {
24015                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24016                 return;
24017             }
24018             synchronized (ActivityManagerService.this) {
24019                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24020             }
24021         }
24022
24023         @Override
24024         public void setDeviceIdleWhitelist(int[] appids) {
24025             synchronized (ActivityManagerService.this) {
24026                 mDeviceIdleWhitelist = appids;
24027             }
24028         }
24029
24030         @Override
24031         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24032             synchronized (ActivityManagerService.this) {
24033                 mDeviceIdleTempWhitelist = appids;
24034                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24035             }
24036         }
24037
24038         @Override
24039         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24040                 int userId) {
24041             Preconditions.checkNotNull(values, "Configuration must not be null");
24042             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24043             synchronized (ActivityManagerService.this) {
24044                 updateConfigurationLocked(values, null, false, true, userId,
24045                         false /* deferResume */);
24046             }
24047         }
24048
24049         @Override
24050         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24051                 Bundle bOptions) {
24052             Preconditions.checkNotNull(intents, "intents");
24053             final String[] resolvedTypes = new String[intents.length];
24054             for (int i = 0; i < intents.length; i++) {
24055                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24056             }
24057
24058             // UID of the package on user userId.
24059             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24060             // packageUid may not be initialized.
24061             int packageUid = 0;
24062             try {
24063                 packageUid = AppGlobals.getPackageManager().getPackageUid(
24064                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24065             } catch (RemoteException e) {
24066                 // Shouldn't happen.
24067             }
24068
24069             synchronized (ActivityManagerService.this) {
24070                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24071                         /*resultTo*/ null, bOptions, userId);
24072             }
24073         }
24074
24075         @Override
24076         public int getUidProcessState(int uid) {
24077             return getUidState(uid);
24078         }
24079
24080         @Override
24081         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24082             synchronized (ActivityManagerService.this) {
24083
24084                 // We might change the visibilities here, so prepare an empty app transition which
24085                 // might be overridden later if we actually change visibilities.
24086                 final boolean wasTransitionSet =
24087                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24088                 if (!wasTransitionSet) {
24089                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24090                             false /* alwaysKeepCurrent */);
24091                 }
24092                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24093
24094                 // If there was a transition set already we don't want to interfere with it as we
24095                 // might be starting it too early.
24096                 if (!wasTransitionSet) {
24097                     mWindowManager.executeAppTransition();
24098                 }
24099             }
24100             if (callback != null) {
24101                 callback.run();
24102             }
24103         }
24104
24105         @Override
24106         public boolean isSystemReady() {
24107             // no need to synchronize(this) just to read & return the value
24108             return mSystemReady;
24109         }
24110
24111         @Override
24112         public void notifyKeyguardTrustedChanged() {
24113             synchronized (ActivityManagerService.this) {
24114                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24115                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24116                 }
24117             }
24118         }
24119
24120         /**
24121          * Sets if the given pid has an overlay UI or not.
24122          *
24123          * @param pid The pid we are setting overlay UI for.
24124          * @param hasOverlayUi True if the process has overlay UI.
24125          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24126          */
24127         @Override
24128         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24129             synchronized (ActivityManagerService.this) {
24130                 final ProcessRecord pr;
24131                 synchronized (mPidsSelfLocked) {
24132                     pr = mPidsSelfLocked.get(pid);
24133                     if (pr == null) {
24134                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24135                         return;
24136                     }
24137                 }
24138                 if (pr.hasOverlayUi == hasOverlayUi) {
24139                     return;
24140                 }
24141                 pr.hasOverlayUi = hasOverlayUi;
24142                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24143                 updateOomAdjLocked(pr, true);
24144             }
24145         }
24146
24147         /**
24148          * Called after the network policy rules are updated by
24149          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24150          * and {@param procStateSeq}.
24151          */
24152         @Override
24153         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24154             if (DEBUG_NETWORK) {
24155                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24156                         + uid + " seq: " + procStateSeq);
24157             }
24158             UidRecord record;
24159             synchronized (ActivityManagerService.this) {
24160                 record = mActiveUids.get(uid);
24161                 if (record == null) {
24162                     if (DEBUG_NETWORK) {
24163                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24164                                 + " procStateSeq: " + procStateSeq);
24165                     }
24166                     return;
24167                 }
24168             }
24169             synchronized (record.networkStateLock) {
24170                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24171                     if (DEBUG_NETWORK) {
24172                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24173                                 + " been handled for uid: " + uid);
24174                     }
24175                     return;
24176                 }
24177                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24178                 if (record.curProcStateSeq > procStateSeq) {
24179                     if (DEBUG_NETWORK) {
24180                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24181                                 + ", curProcstateSeq: " + record.curProcStateSeq
24182                                 + ", procStateSeq: " + procStateSeq);
24183                     }
24184                     return;
24185                 }
24186                 if (record.waitingForNetwork) {
24187                     if (DEBUG_NETWORK) {
24188                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24189                                 + ", procStateSeq: " + procStateSeq);
24190                     }
24191                     record.networkStateLock.notifyAll();
24192                 }
24193             }
24194         }
24195
24196         /**
24197          * Called after virtual display Id is updated by
24198          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24199          * {@param vrVr2dDisplayId}.
24200          */
24201         @Override
24202         public void setVr2dDisplayId(int vr2dDisplayId) {
24203             if (DEBUG_STACK) {
24204                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24205                         vr2dDisplayId);
24206             }
24207             synchronized (ActivityManagerService.this) {
24208                 mVr2dDisplayId = vr2dDisplayId;
24209             }
24210         }
24211
24212         @Override
24213         public void saveANRState(String reason) {
24214             synchronized (ActivityManagerService.this) {
24215                 final StringWriter sw = new StringWriter();
24216                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24217                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24218                 if (reason != null) {
24219                     pw.println("  Reason: " + reason);
24220                 }
24221                 pw.println();
24222                 mActivityStarter.dump(pw, "  ", null);
24223                 pw.println();
24224                 pw.println("-------------------------------------------------------------------------------");
24225                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24226                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24227                         "" /* header */);
24228                 pw.println();
24229                 pw.close();
24230
24231                 mLastANRState = sw.toString();
24232             }
24233         }
24234
24235         @Override
24236         public void clearSavedANRState() {
24237             synchronized (ActivityManagerService.this) {
24238                 mLastANRState = null;
24239             }
24240         }
24241
24242         @Override
24243         public void setFocusedActivity(IBinder token) {
24244             synchronized (ActivityManagerService.this) {
24245                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24246                 if (r == null) {
24247                     throw new IllegalArgumentException(
24248                             "setFocusedActivity: No activity record matching token=" + token);
24249                 }
24250                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24251                         r, "setFocusedActivity")) {
24252                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
24253                 }
24254             }
24255         }
24256
24257         @Override
24258         public void registerScreenObserver(ScreenObserver observer) {
24259             mScreenObservers.add(observer);
24260         }
24261     }
24262
24263     /**
24264      * Called by app main thread to wait for the network policy rules to get updated.
24265      *
24266      * @param procStateSeq The sequence number indicating the process state change that the main
24267      *                     thread is interested in.
24268      */
24269     @Override
24270     public void waitForNetworkStateUpdate(long procStateSeq) {
24271         final int callingUid = Binder.getCallingUid();
24272         if (DEBUG_NETWORK) {
24273             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24274         }
24275         UidRecord record;
24276         synchronized (this) {
24277             record = mActiveUids.get(callingUid);
24278             if (record == null) {
24279                 return;
24280             }
24281         }
24282         synchronized (record.networkStateLock) {
24283             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24284                 if (DEBUG_NETWORK) {
24285                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24286                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24287                             + " lastProcStateSeqDispatchedToObservers: "
24288                             + record.lastDispatchedProcStateSeq);
24289                 }
24290                 return;
24291             }
24292             if (record.curProcStateSeq > procStateSeq) {
24293                 if (DEBUG_NETWORK) {
24294                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24295                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24296                             + ", procStateSeq: " + procStateSeq);
24297                 }
24298                 return;
24299             }
24300             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24301                 if (DEBUG_NETWORK) {
24302                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24303                             + procStateSeq + ", so no need to wait. Uid: "
24304                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24305                             + record.lastNetworkUpdatedProcStateSeq);
24306                 }
24307                 return;
24308             }
24309             try {
24310                 if (DEBUG_NETWORK) {
24311                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24312                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24313                 }
24314                 final long startTime = SystemClock.uptimeMillis();
24315                 record.waitingForNetwork = true;
24316                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24317                 record.waitingForNetwork = false;
24318                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24319                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24320                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24321                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24322                             + procStateSeq + " UidRec: " + record
24323                             + " validateUidRec: " + mValidateUids.get(callingUid));
24324                 }
24325             } catch (InterruptedException e) {
24326                 Thread.currentThread().interrupt();
24327             }
24328         }
24329     }
24330
24331     public void waitForBroadcastIdle(PrintWriter pw) {
24332         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24333         while (true) {
24334             boolean idle = true;
24335             synchronized (this) {
24336                 for (BroadcastQueue queue : mBroadcastQueues) {
24337                     if (!queue.isIdle()) {
24338                         final String msg = "Waiting for queue " + queue + " to become idle...";
24339                         pw.println(msg);
24340                         pw.flush();
24341                         Slog.v(TAG, msg);
24342                         idle = false;
24343                     }
24344                 }
24345             }
24346
24347             if (idle) {
24348                 final String msg = "All broadcast queues are idle!";
24349                 pw.println(msg);
24350                 pw.flush();
24351                 Slog.v(TAG, msg);
24352                 return;
24353             } else {
24354                 SystemClock.sleep(1000);
24355             }
24356         }
24357     }
24358
24359     /**
24360      * Return the user id of the last resumed activity.
24361      */
24362     @Override
24363     public @UserIdInt int getLastResumedActivityUserId() {
24364         enforceCallingPermission(
24365                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24366         synchronized (this) {
24367             if (mLastResumedActivity == null) {
24368                 return mUserController.getCurrentUserIdLocked();
24369             }
24370             return mLastResumedActivity.userId;
24371         }
24372     }
24373
24374     /**
24375      * An implementation of IAppTask, that allows an app to manage its own tasks via
24376      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24377      * only the process that calls getAppTasks() can call the AppTask methods.
24378      */
24379     class AppTaskImpl extends IAppTask.Stub {
24380         private int mTaskId;
24381         private int mCallingUid;
24382
24383         public AppTaskImpl(int taskId, int callingUid) {
24384             mTaskId = taskId;
24385             mCallingUid = callingUid;
24386         }
24387
24388         private void checkCaller() {
24389             if (mCallingUid != Binder.getCallingUid()) {
24390                 throw new SecurityException("Caller " + mCallingUid
24391                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24392             }
24393         }
24394
24395         @Override
24396         public void finishAndRemoveTask() {
24397             checkCaller();
24398
24399             synchronized (ActivityManagerService.this) {
24400                 long origId = Binder.clearCallingIdentity();
24401                 try {
24402                     // We remove the task from recents to preserve backwards
24403                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24404                             REMOVE_FROM_RECENTS)) {
24405                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24406                     }
24407                 } finally {
24408                     Binder.restoreCallingIdentity(origId);
24409                 }
24410             }
24411         }
24412
24413         @Override
24414         public ActivityManager.RecentTaskInfo getTaskInfo() {
24415             checkCaller();
24416
24417             synchronized (ActivityManagerService.this) {
24418                 long origId = Binder.clearCallingIdentity();
24419                 try {
24420                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24421                     if (tr == null) {
24422                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24423                     }
24424                     return createRecentTaskInfoFromTaskRecord(tr);
24425                 } finally {
24426                     Binder.restoreCallingIdentity(origId);
24427                 }
24428             }
24429         }
24430
24431         @Override
24432         public void moveToFront() {
24433             checkCaller();
24434             // Will bring task to front if it already has a root activity.
24435             final long origId = Binder.clearCallingIdentity();
24436             try {
24437                 synchronized (this) {
24438                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24439                 }
24440             } finally {
24441                 Binder.restoreCallingIdentity(origId);
24442             }
24443         }
24444
24445         @Override
24446         public int startActivity(IBinder whoThread, String callingPackage,
24447                 Intent intent, String resolvedType, Bundle bOptions) {
24448             checkCaller();
24449
24450             int callingUser = UserHandle.getCallingUserId();
24451             TaskRecord tr;
24452             IApplicationThread appThread;
24453             synchronized (ActivityManagerService.this) {
24454                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24455                 if (tr == null) {
24456                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24457                 }
24458                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24459                 if (appThread == null) {
24460                     throw new IllegalArgumentException("Bad app thread " + appThread);
24461                 }
24462             }
24463             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24464                     resolvedType, null, null, null, null, 0, 0, null, null,
24465                     null, bOptions, false, callingUser, tr, "AppTaskImpl");
24466         }
24467
24468         @Override
24469         public void setExcludeFromRecents(boolean exclude) {
24470             checkCaller();
24471
24472             synchronized (ActivityManagerService.this) {
24473                 long origId = Binder.clearCallingIdentity();
24474                 try {
24475                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24476                     if (tr == null) {
24477                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24478                     }
24479                     Intent intent = tr.getBaseIntent();
24480                     if (exclude) {
24481                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24482                     } else {
24483                         intent.setFlags(intent.getFlags()
24484                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24485                     }
24486                 } finally {
24487                     Binder.restoreCallingIdentity(origId);
24488                 }
24489             }
24490         }
24491     }
24492
24493     /**
24494      * Kill processes for the user with id userId and that depend on the package named packageName
24495      */
24496     @Override
24497     public void killPackageDependents(String packageName, int userId) {
24498         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24499         if (packageName == null) {
24500             throw new NullPointerException(
24501                     "Cannot kill the dependents of a package without its name.");
24502         }
24503
24504         long callingId = Binder.clearCallingIdentity();
24505         IPackageManager pm = AppGlobals.getPackageManager();
24506         int pkgUid = -1;
24507         try {
24508             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24509         } catch (RemoteException e) {
24510         }
24511         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24512             throw new IllegalArgumentException(
24513                     "Cannot kill dependents of non-existing package " + packageName);
24514         }
24515         try {
24516             synchronized(this) {
24517                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24518                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24519                         "dep: " + packageName);
24520             }
24521         } finally {
24522             Binder.restoreCallingIdentity(callingId);
24523         }
24524     }
24525
24526     @Override
24527     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24528             throws RemoteException {
24529         final long callingId = Binder.clearCallingIdentity();
24530         try {
24531             mKeyguardController.dismissKeyguard(token, callback);
24532         } finally {
24533             Binder.restoreCallingIdentity(callingId);
24534         }
24535     }
24536
24537     @Override
24538     public int restartUserInBackground(final int userId) {
24539         return mUserController.restartUser(userId, /* foreground */ false);
24540     }
24541
24542     @Override
24543     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24544         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24545                 "scheduleApplicationInfoChanged()");
24546
24547         synchronized (this) {
24548             final long origId = Binder.clearCallingIdentity();
24549             try {
24550                 updateApplicationInfoLocked(packageNames, userId);
24551             } finally {
24552                 Binder.restoreCallingIdentity(origId);
24553             }
24554         }
24555     }
24556
24557     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24558         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24559         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24560             final ProcessRecord app = mLruProcesses.get(i);
24561             if (app.thread == null) {
24562                 continue;
24563             }
24564
24565             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24566                 continue;
24567             }
24568
24569             final int packageCount = app.pkgList.size();
24570             for (int j = 0; j < packageCount; j++) {
24571                 final String packageName = app.pkgList.keyAt(j);
24572                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24573                     try {
24574                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24575                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24576                         if (ai != null) {
24577                             app.thread.scheduleApplicationInfoChanged(ai);
24578                         }
24579                     } catch (RemoteException e) {
24580                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24581                                     packageName, app));
24582                     }
24583                 }
24584             }
24585         }
24586     }
24587
24588     /**
24589      * Attach an agent to the specified process (proces name or PID)
24590      */
24591     public void attachAgent(String process, String path) {
24592         try {
24593             synchronized (this) {
24594                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24595                 if (proc == null || proc.thread == null) {
24596                     throw new IllegalArgumentException("Unknown process: " + process);
24597                 }
24598
24599                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24600                 if (!isDebuggable) {
24601                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24602                         throw new SecurityException("Process not debuggable: " + proc);
24603                     }
24604                 }
24605
24606                 proc.thread.attachAgent(path);
24607             }
24608         } catch (RemoteException e) {
24609             throw new IllegalStateException("Process disappeared");
24610         }
24611     }
24612
24613     @VisibleForTesting
24614     public static class Injector {
24615         private NetworkManagementInternal mNmi;
24616
24617         public Context getContext() {
24618             return null;
24619         }
24620
24621         public AppOpsService getAppOpsService(File file, Handler handler) {
24622             return new AppOpsService(file, handler);
24623         }
24624
24625         public Handler getUiHandler(ActivityManagerService service) {
24626             return service.new UiHandler();
24627         }
24628
24629         public boolean isNetworkRestrictedForUid(int uid) {
24630             if (ensureHasNetworkManagementInternal()) {
24631                 return mNmi.isNetworkRestrictedForUid(uid);
24632             }
24633             return false;
24634         }
24635
24636         private boolean ensureHasNetworkManagementInternal() {
24637             if (mNmi == null) {
24638                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24639             }
24640             return mNmi != null;
24641         }
24642     }
24643
24644     @Override
24645     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24646             throws RemoteException {
24647         synchronized (this) {
24648             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24649             if (r == null) {
24650                 return;
24651             }
24652             final long origId = Binder.clearCallingIdentity();
24653             try {
24654                 r.setShowWhenLocked(showWhenLocked);
24655             } finally {
24656                 Binder.restoreCallingIdentity(origId);
24657             }
24658         }
24659     }
24660
24661     @Override
24662     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24663         synchronized (this) {
24664             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24665             if (r == null) {
24666                 return;
24667             }
24668             final long origId = Binder.clearCallingIdentity();
24669             try {
24670                 r.setTurnScreenOn(turnScreenOn);
24671             } finally {
24672                 Binder.restoreCallingIdentity(origId);
24673             }
24674         }
24675     }
24676 }