OSDN Git Service

Merge "Add dalvik.vm.minidebuginfo property for ART"
[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
1497     /**
1498      * Stores a map of process name -> agent string. When a process is started and mAgentAppMap
1499      * is not null, this map is checked and the mapped agent installed during bind-time. Note:
1500      * A non-null agent in mProfileInfo overrides this.
1501      */
1502     private @Nullable Map<String, String> mAppAgentMap = null;
1503
1504     int mProfileType = 0;
1505     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1506     String mMemWatchDumpProcName;
1507     String mMemWatchDumpFile;
1508     int mMemWatchDumpPid;
1509     int mMemWatchDumpUid;
1510     String mTrackAllocationApp = null;
1511     String mNativeDebuggingApp = null;
1512
1513     final long[] mTmpLong = new long[2];
1514
1515     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1516
1517     /**
1518      * A global counter for generating sequence numbers.
1519      * This value will be used when incrementing sequence numbers in individual uidRecords.
1520      *
1521      * Having a global counter ensures that seq numbers are monotonically increasing for a
1522      * particular uid even when the uidRecord is re-created.
1523      */
1524     @GuardedBy("this")
1525     @VisibleForTesting
1526     long mProcStateSeqCounter = 0;
1527
1528     private final Injector mInjector;
1529
1530     static final class ProcessChangeItem {
1531         static final int CHANGE_ACTIVITIES = 1<<0;
1532         int changes;
1533         int uid;
1534         int pid;
1535         int processState;
1536         boolean foregroundActivities;
1537     }
1538
1539     static final class UidObserverRegistration {
1540         final int uid;
1541         final String pkg;
1542         final int which;
1543         final int cutpoint;
1544
1545         final SparseIntArray lastProcStates;
1546
1547         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1548             uid = _uid;
1549             pkg = _pkg;
1550             which = _which;
1551             cutpoint = _cutpoint;
1552             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1553                 lastProcStates = new SparseIntArray();
1554             } else {
1555                 lastProcStates = null;
1556             }
1557         }
1558     }
1559
1560     final List<ScreenObserver> mScreenObservers = new ArrayList<>();
1561
1562     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1563     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1564
1565     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1566     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1567
1568     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1569     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1570
1571     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1572     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1573
1574     OomAdjObserver mCurOomAdjObserver;
1575     int mCurOomAdjUid;
1576
1577     interface OomAdjObserver {
1578         void onOomAdjMessage(String msg);
1579     }
1580
1581     /**
1582      * Runtime CPU use collection thread.  This object's lock is used to
1583      * perform synchronization with the thread (notifying it to run).
1584      */
1585     final Thread mProcessCpuThread;
1586
1587     /**
1588      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1589      * Must acquire this object's lock when accessing it.
1590      * NOTE: this lock will be held while doing long operations (trawling
1591      * through all processes in /proc), so it should never be acquired by
1592      * any critical paths such as when holding the main activity manager lock.
1593      */
1594     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1595             MONITOR_THREAD_CPU_USAGE);
1596     final AtomicLong mLastCpuTime = new AtomicLong(0);
1597     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1598     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1599
1600     long mLastWriteTime = 0;
1601
1602     /**
1603      * Used to retain an update lock when the foreground activity is in
1604      * immersive mode.
1605      */
1606     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1607
1608     /**
1609      * Set to true after the system has finished booting.
1610      */
1611     boolean mBooted = false;
1612
1613     WindowManagerService mWindowManager;
1614     final ActivityThread mSystemThread;
1615
1616     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1617         final ProcessRecord mApp;
1618         final int mPid;
1619         final IApplicationThread mAppThread;
1620
1621         AppDeathRecipient(ProcessRecord app, int pid,
1622                 IApplicationThread thread) {
1623             if (DEBUG_ALL) Slog.v(
1624                 TAG, "New death recipient " + this
1625                 + " for thread " + thread.asBinder());
1626             mApp = app;
1627             mPid = pid;
1628             mAppThread = thread;
1629         }
1630
1631         @Override
1632         public void binderDied() {
1633             if (DEBUG_ALL) Slog.v(
1634                 TAG, "Death received in " + this
1635                 + " for thread " + mAppThread.asBinder());
1636             synchronized(ActivityManagerService.this) {
1637                 appDiedLocked(mApp, mPid, mAppThread, true);
1638             }
1639         }
1640     }
1641
1642     static final int SHOW_ERROR_UI_MSG = 1;
1643     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1644     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1645     static final int UPDATE_CONFIGURATION_MSG = 4;
1646     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1647     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1648     static final int SERVICE_TIMEOUT_MSG = 12;
1649     static final int UPDATE_TIME_ZONE = 13;
1650     static final int SHOW_UID_ERROR_UI_MSG = 14;
1651     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1652     static final int PROC_START_TIMEOUT_MSG = 20;
1653     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1654     static final int KILL_APPLICATION_MSG = 22;
1655     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1656     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1657     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1658     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1659     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1660     static final int CLEAR_DNS_CACHE_MSG = 28;
1661     static final int UPDATE_HTTP_PROXY_MSG = 29;
1662     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1663     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1664     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1665     static final int REPORT_MEM_USAGE_MSG = 33;
1666     static final int REPORT_USER_SWITCH_MSG = 34;
1667     static final int CONTINUE_USER_SWITCH_MSG = 35;
1668     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1669     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1670     static final int PERSIST_URI_GRANTS_MSG = 38;
1671     static final int REQUEST_ALL_PSS_MSG = 39;
1672     static final int START_PROFILES_MSG = 40;
1673     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1674     static final int SYSTEM_USER_START_MSG = 42;
1675     static final int SYSTEM_USER_CURRENT_MSG = 43;
1676     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1677     static final int FINISH_BOOTING_MSG = 45;
1678     static final int START_USER_SWITCH_UI_MSG = 46;
1679     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1680     static final int DISMISS_DIALOG_UI_MSG = 48;
1681     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1682     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1683     static final int DELETE_DUMPHEAP_MSG = 51;
1684     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1685     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1686     static final int REPORT_TIME_TRACKER_MSG = 54;
1687     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1688     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1689     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1690     static final int IDLE_UIDS_MSG = 58;
1691     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1692     static final int LOG_STACK_STATE = 60;
1693     static final int VR_MODE_CHANGE_MSG = 61;
1694     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1695     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1696     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1697     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1698     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1699     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1700     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1701     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1702     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1703     static final int DISPATCH_SCREEN_AWAKE_MSG = 71;
1704     static final int DISPATCH_SCREEN_KEYGUARD_MSG = 72;
1705     static final int START_USER_SWITCH_FG_MSG = 712;
1706     static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1707
1708     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1709     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1710     static final int FIRST_COMPAT_MODE_MSG = 300;
1711     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1712
1713     static ServiceThread sKillThread = null;
1714     static KillHandler sKillHandler = null;
1715
1716     CompatModeDialog mCompatModeDialog;
1717     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1718     long mLastMemUsageReportTime = 0;
1719
1720     /**
1721      * Flag whether the current user is a "monkey", i.e. whether
1722      * the UI is driven by a UI automation tool.
1723      */
1724     private boolean mUserIsMonkey;
1725
1726     /** Flag whether the device has a Recents UI */
1727     boolean mHasRecents;
1728
1729     /** The dimensions of the thumbnails in the Recents UI. */
1730     int mThumbnailWidth;
1731     int mThumbnailHeight;
1732     float mFullscreenThumbnailScale;
1733
1734     final ServiceThread mHandlerThread;
1735     final MainHandler mHandler;
1736     final Handler mUiHandler;
1737
1738     final ActivityManagerConstants mConstants;
1739
1740     PackageManagerInternal mPackageManagerInt;
1741
1742     // VoiceInteraction session ID that changes for each new request except when
1743     // being called for multiwindow assist in a single session.
1744     private int mViSessionId = 1000;
1745
1746     final boolean mPermissionReviewRequired;
1747
1748     private static String sTheRealBuildSerial = Build.UNKNOWN;
1749
1750     /**
1751      * Current global configuration information. Contains general settings for the entire system,
1752      * also corresponds to the merged configuration of the default display.
1753      */
1754     Configuration getGlobalConfiguration() {
1755         return mStackSupervisor.getConfiguration();
1756     }
1757
1758     final class KillHandler extends Handler {
1759         static final int KILL_PROCESS_GROUP_MSG = 4000;
1760
1761         public KillHandler(Looper looper) {
1762             super(looper, null, true);
1763         }
1764
1765         @Override
1766         public void handleMessage(Message msg) {
1767             switch (msg.what) {
1768                 case KILL_PROCESS_GROUP_MSG:
1769                 {
1770                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1771                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1772                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1773                 }
1774                 break;
1775
1776                 default:
1777                     super.handleMessage(msg);
1778             }
1779         }
1780     }
1781
1782     final class UiHandler extends Handler {
1783         public UiHandler() {
1784             super(com.android.server.UiThread.get().getLooper(), null, true);
1785         }
1786
1787         @Override
1788         public void handleMessage(Message msg) {
1789             switch (msg.what) {
1790             case SHOW_ERROR_UI_MSG: {
1791                 mAppErrors.handleShowAppErrorUi(msg);
1792                 ensureBootCompleted();
1793             } break;
1794             case SHOW_NOT_RESPONDING_UI_MSG: {
1795                 mAppErrors.handleShowAnrUi(msg);
1796                 ensureBootCompleted();
1797             } break;
1798             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1799                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1800                 synchronized (ActivityManagerService.this) {
1801                     ProcessRecord proc = (ProcessRecord) data.get("app");
1802                     if (proc == null) {
1803                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1804                         break;
1805                     }
1806                     if (proc.crashDialog != null) {
1807                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1808                         return;
1809                     }
1810                     AppErrorResult res = (AppErrorResult) data.get("result");
1811                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1812                         Dialog d = new StrictModeViolationDialog(mUiContext,
1813                                 ActivityManagerService.this, res, proc);
1814                         d.show();
1815                         proc.crashDialog = d;
1816                     } else {
1817                         // The device is asleep, so just pretend that the user
1818                         // saw a crash dialog and hit "force quit".
1819                         res.set(0);
1820                     }
1821                 }
1822                 ensureBootCompleted();
1823             } break;
1824             case SHOW_FACTORY_ERROR_UI_MSG: {
1825                 Dialog d = new FactoryErrorDialog(
1826                         mUiContext, msg.getData().getCharSequence("msg"));
1827                 d.show();
1828                 ensureBootCompleted();
1829             } break;
1830             case WAIT_FOR_DEBUGGER_UI_MSG: {
1831                 synchronized (ActivityManagerService.this) {
1832                     ProcessRecord app = (ProcessRecord)msg.obj;
1833                     if (msg.arg1 != 0) {
1834                         if (!app.waitedForDebugger) {
1835                             Dialog d = new AppWaitingForDebuggerDialog(
1836                                     ActivityManagerService.this,
1837                                     mUiContext, app);
1838                             app.waitDialog = d;
1839                             app.waitedForDebugger = true;
1840                             d.show();
1841                         }
1842                     } else {
1843                         if (app.waitDialog != null) {
1844                             app.waitDialog.dismiss();
1845                             app.waitDialog = null;
1846                         }
1847                     }
1848                 }
1849             } break;
1850             case SHOW_UID_ERROR_UI_MSG: {
1851                 if (mShowDialogs) {
1852                     AlertDialog d = new BaseErrorDialog(mUiContext);
1853                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1854                     d.setCancelable(false);
1855                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1856                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1857                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1858                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1859                     d.show();
1860                 }
1861             } break;
1862             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1863                 if (mShowDialogs) {
1864                     AlertDialog d = new BaseErrorDialog(mUiContext);
1865                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1866                     d.setCancelable(false);
1867                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1868                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1869                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1870                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1871                     d.show();
1872                 }
1873             } break;
1874             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1875                 synchronized (ActivityManagerService.this) {
1876                     ActivityRecord ar = (ActivityRecord) msg.obj;
1877                     if (mCompatModeDialog != null) {
1878                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1879                                 ar.info.applicationInfo.packageName)) {
1880                             return;
1881                         }
1882                         mCompatModeDialog.dismiss();
1883                         mCompatModeDialog = null;
1884                     }
1885                     if (ar != null && false) {
1886                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1887                                 ar.packageName)) {
1888                             int mode = mCompatModePackages.computeCompatModeLocked(
1889                                     ar.info.applicationInfo);
1890                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1891                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1892                                 mCompatModeDialog = new CompatModeDialog(
1893                                         ActivityManagerService.this, mUiContext,
1894                                         ar.info.applicationInfo);
1895                                 mCompatModeDialog.show();
1896                             }
1897                         }
1898                     }
1899                 }
1900                 break;
1901             }
1902             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1903                 synchronized (ActivityManagerService.this) {
1904                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1905                     if (mUnsupportedDisplaySizeDialog != null) {
1906                         mUnsupportedDisplaySizeDialog.dismiss();
1907                         mUnsupportedDisplaySizeDialog = null;
1908                     }
1909                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1910                             ar.packageName)) {
1911                         // TODO(multi-display): Show dialog on appropriate display.
1912                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1913                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1914                         mUnsupportedDisplaySizeDialog.show();
1915                     }
1916                 }
1917                 break;
1918             }
1919             case START_USER_SWITCH_UI_MSG: {
1920                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1921                 break;
1922             }
1923             case DISMISS_DIALOG_UI_MSG: {
1924                 final Dialog d = (Dialog) msg.obj;
1925                 d.dismiss();
1926                 break;
1927             }
1928             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1929                 dispatchProcessesChanged();
1930                 break;
1931             }
1932             case DISPATCH_PROCESS_DIED_UI_MSG: {
1933                 final int pid = msg.arg1;
1934                 final int uid = msg.arg2;
1935                 dispatchProcessDied(pid, uid);
1936                 break;
1937             }
1938             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1939                 dispatchUidsChanged();
1940             } break;
1941             case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1942                 dispatchOomAdjObserver((String)msg.obj);
1943             } break;
1944             case PUSH_TEMP_WHITELIST_UI_MSG: {
1945                 pushTempWhitelist();
1946             } break;
1947             }
1948         }
1949     }
1950
1951     final class MainHandler extends Handler {
1952         public MainHandler(Looper looper) {
1953             super(looper, null, true);
1954         }
1955
1956         @Override
1957         public void handleMessage(Message msg) {
1958             switch (msg.what) {
1959             case UPDATE_CONFIGURATION_MSG: {
1960                 final ContentResolver resolver = mContext.getContentResolver();
1961                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1962                         msg.arg1);
1963             } break;
1964             case GC_BACKGROUND_PROCESSES_MSG: {
1965                 synchronized (ActivityManagerService.this) {
1966                     performAppGcsIfAppropriateLocked();
1967                 }
1968             } break;
1969             case SERVICE_TIMEOUT_MSG: {
1970                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1971             } break;
1972             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1973                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1974             } break;
1975             case SERVICE_FOREGROUND_CRASH_MSG: {
1976                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1977             } break;
1978             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1979                 RemoteCallbackList<IResultReceiver> callbacks
1980                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1981                 int N = callbacks.beginBroadcast();
1982                 for (int i = 0; i < N; i++) {
1983                     try {
1984                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1985                     } catch (RemoteException e) {
1986                     }
1987                 }
1988                 callbacks.finishBroadcast();
1989             } break;
1990             case UPDATE_TIME_ZONE: {
1991                 synchronized (ActivityManagerService.this) {
1992                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1993                         ProcessRecord r = mLruProcesses.get(i);
1994                         if (r.thread != null) {
1995                             try {
1996                                 r.thread.updateTimeZone();
1997                             } catch (RemoteException ex) {
1998                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1999                             }
2000                         }
2001                     }
2002                 }
2003             } break;
2004             case CLEAR_DNS_CACHE_MSG: {
2005                 synchronized (ActivityManagerService.this) {
2006                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2007                         ProcessRecord r = mLruProcesses.get(i);
2008                         if (r.thread != null) {
2009                             try {
2010                                 r.thread.clearDnsCache();
2011                             } catch (RemoteException ex) {
2012                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2013                             }
2014                         }
2015                     }
2016                 }
2017             } break;
2018             case UPDATE_HTTP_PROXY_MSG: {
2019                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2020                 String host = "";
2021                 String port = "";
2022                 String exclList = "";
2023                 Uri pacFileUrl = Uri.EMPTY;
2024                 if (proxy != null) {
2025                     host = proxy.getHost();
2026                     port = Integer.toString(proxy.getPort());
2027                     exclList = proxy.getExclusionListAsString();
2028                     pacFileUrl = proxy.getPacFileUrl();
2029                 }
2030                 synchronized (ActivityManagerService.this) {
2031                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2032                         ProcessRecord r = mLruProcesses.get(i);
2033                         if (r.thread != null) {
2034                             try {
2035                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2036                             } catch (RemoteException ex) {
2037                                 Slog.w(TAG, "Failed to update http proxy for: " +
2038                                         r.info.processName);
2039                             }
2040                         }
2041                     }
2042                 }
2043             } break;
2044             case PROC_START_TIMEOUT_MSG: {
2045                 ProcessRecord app = (ProcessRecord)msg.obj;
2046                 synchronized (ActivityManagerService.this) {
2047                     processStartTimedOutLocked(app);
2048                 }
2049             } break;
2050             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2051                 ProcessRecord app = (ProcessRecord)msg.obj;
2052                 synchronized (ActivityManagerService.this) {
2053                     processContentProviderPublishTimedOutLocked(app);
2054                 }
2055             } break;
2056             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2057                 synchronized (ActivityManagerService.this) {
2058                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2059                 }
2060             } break;
2061             case KILL_APPLICATION_MSG: {
2062                 synchronized (ActivityManagerService.this) {
2063                     final int appId = msg.arg1;
2064                     final int userId = msg.arg2;
2065                     Bundle bundle = (Bundle)msg.obj;
2066                     String pkg = bundle.getString("pkg");
2067                     String reason = bundle.getString("reason");
2068                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2069                             false, userId, reason);
2070                 }
2071             } break;
2072             case FINALIZE_PENDING_INTENT_MSG: {
2073                 ((PendingIntentRecord)msg.obj).completeFinalize();
2074             } break;
2075             case POST_HEAVY_NOTIFICATION_MSG: {
2076                 INotificationManager inm = NotificationManager.getService();
2077                 if (inm == null) {
2078                     return;
2079                 }
2080
2081                 ActivityRecord root = (ActivityRecord)msg.obj;
2082                 ProcessRecord process = root.app;
2083                 if (process == null) {
2084                     return;
2085                 }
2086
2087                 try {
2088                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2089                     String text = mContext.getString(R.string.heavy_weight_notification,
2090                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2091                     Notification notification =
2092                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2093                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2094                             .setWhen(0)
2095                             .setOngoing(true)
2096                             .setTicker(text)
2097                             .setColor(mContext.getColor(
2098                                     com.android.internal.R.color.system_notification_accent_color))
2099                             .setContentTitle(text)
2100                             .setContentText(
2101                                     mContext.getText(R.string.heavy_weight_notification_detail))
2102                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2103                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2104                                     new UserHandle(root.userId)))
2105                             .build();
2106                     try {
2107                         inm.enqueueNotificationWithTag("android", "android", null,
2108                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2109                                 notification, root.userId);
2110                     } catch (RuntimeException e) {
2111                         Slog.w(ActivityManagerService.TAG,
2112                                 "Error showing notification for heavy-weight app", e);
2113                     } catch (RemoteException e) {
2114                     }
2115                 } catch (NameNotFoundException e) {
2116                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2117                 }
2118             } break;
2119             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2120                 INotificationManager inm = NotificationManager.getService();
2121                 if (inm == null) {
2122                     return;
2123                 }
2124                 try {
2125                     inm.cancelNotificationWithTag("android", null,
2126                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2127                 } catch (RuntimeException e) {
2128                     Slog.w(ActivityManagerService.TAG,
2129                             "Error canceling notification for service", e);
2130                 } catch (RemoteException e) {
2131                 }
2132             } break;
2133             case CHECK_EXCESSIVE_POWER_USE_MSG: {
2134                 synchronized (ActivityManagerService.this) {
2135                     checkExcessivePowerUsageLocked();
2136                     removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2137                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2138                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2139                 }
2140             } break;
2141             case REPORT_MEM_USAGE_MSG: {
2142                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2143                 Thread thread = new Thread() {
2144                     @Override public void run() {
2145                         reportMemUsage(memInfos);
2146                     }
2147                 };
2148                 thread.start();
2149                 break;
2150             }
2151             case START_USER_SWITCH_FG_MSG: {
2152                 mUserController.startUserInForeground(msg.arg1);
2153                 break;
2154             }
2155             case REPORT_USER_SWITCH_MSG: {
2156                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2157                 break;
2158             }
2159             case CONTINUE_USER_SWITCH_MSG: {
2160                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2161                 break;
2162             }
2163             case USER_SWITCH_TIMEOUT_MSG: {
2164                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2165                 break;
2166             }
2167             case IMMERSIVE_MODE_LOCK_MSG: {
2168                 final boolean nextState = (msg.arg1 != 0);
2169                 if (mUpdateLock.isHeld() != nextState) {
2170                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2171                             "Applying new update lock state '" + nextState
2172                             + "' for " + (ActivityRecord)msg.obj);
2173                     if (nextState) {
2174                         mUpdateLock.acquire();
2175                     } else {
2176                         mUpdateLock.release();
2177                     }
2178                 }
2179                 break;
2180             }
2181             case PERSIST_URI_GRANTS_MSG: {
2182                 writeGrantedUriPermissions();
2183                 break;
2184             }
2185             case REQUEST_ALL_PSS_MSG: {
2186                 synchronized (ActivityManagerService.this) {
2187                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2188                 }
2189                 break;
2190             }
2191             case START_PROFILES_MSG: {
2192                 synchronized (ActivityManagerService.this) {
2193                     mUserController.startProfilesLocked();
2194                 }
2195                 break;
2196             }
2197             case UPDATE_TIME_PREFERENCE_MSG: {
2198                 // The user's time format preference might have changed.
2199                 // For convenience we re-use the Intent extra values.
2200                 synchronized (ActivityManagerService.this) {
2201                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2202                         ProcessRecord r = mLruProcesses.get(i);
2203                         if (r.thread != null) {
2204                             try {
2205                                 r.thread.updateTimePrefs(msg.arg1);
2206                             } catch (RemoteException ex) {
2207                                 Slog.w(TAG, "Failed to update preferences for: "
2208                                         + r.info.processName);
2209                             }
2210                         }
2211                     }
2212                 }
2213                 break;
2214             }
2215             case SYSTEM_USER_START_MSG: {
2216                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2217                         Integer.toString(msg.arg1), msg.arg1);
2218                 mSystemServiceManager.startUser(msg.arg1);
2219                 break;
2220             }
2221             case SYSTEM_USER_UNLOCK_MSG: {
2222                 final int userId = msg.arg1;
2223                 mSystemServiceManager.unlockUser(userId);
2224                 synchronized (ActivityManagerService.this) {
2225                     mRecentTasks.loadUserRecentsLocked(userId);
2226                 }
2227                 if (userId == UserHandle.USER_SYSTEM) {
2228                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2229                 }
2230                 installEncryptionUnawareProviders(userId);
2231                 mUserController.finishUserUnlocked((UserState) msg.obj);
2232                 break;
2233             }
2234             case SYSTEM_USER_CURRENT_MSG: {
2235                 mBatteryStatsService.noteEvent(
2236                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2237                         Integer.toString(msg.arg2), msg.arg2);
2238                 mBatteryStatsService.noteEvent(
2239                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2240                         Integer.toString(msg.arg1), msg.arg1);
2241                 mSystemServiceManager.switchUser(msg.arg1);
2242                 break;
2243             }
2244             case ENTER_ANIMATION_COMPLETE_MSG: {
2245                 synchronized (ActivityManagerService.this) {
2246                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2247                     if (r != null && r.app != null && r.app.thread != null) {
2248                         try {
2249                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2250                         } catch (RemoteException e) {
2251                         }
2252                     }
2253                 }
2254                 break;
2255             }
2256             case FINISH_BOOTING_MSG: {
2257                 if (msg.arg1 != 0) {
2258                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2259                     finishBooting();
2260                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2261                 }
2262                 if (msg.arg2 != 0) {
2263                     enableScreenAfterBoot();
2264                 }
2265                 break;
2266             }
2267             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2268                 try {
2269                     Locale l = (Locale) msg.obj;
2270                     IBinder service = ServiceManager.getService("mount");
2271                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2272                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2273                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2274                 } catch (RemoteException e) {
2275                     Log.e(TAG, "Error storing locale for decryption UI", e);
2276                 }
2277                 break;
2278             }
2279             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2280                 final int uid = msg.arg1;
2281                 final byte[] firstPacket = (byte[]) msg.obj;
2282
2283                 synchronized (mPidsSelfLocked) {
2284                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2285                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2286                         if (p.uid == uid) {
2287                             try {
2288                                 p.thread.notifyCleartextNetwork(firstPacket);
2289                             } catch (RemoteException ignored) {
2290                             }
2291                         }
2292                     }
2293                 }
2294                 break;
2295             }
2296             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2297                 final String procName;
2298                 final int uid;
2299                 final long memLimit;
2300                 final String reportPackage;
2301                 synchronized (ActivityManagerService.this) {
2302                     procName = mMemWatchDumpProcName;
2303                     uid = mMemWatchDumpUid;
2304                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2305                     if (val == null) {
2306                         val = mMemWatchProcesses.get(procName, 0);
2307                     }
2308                     if (val != null) {
2309                         memLimit = val.first;
2310                         reportPackage = val.second;
2311                     } else {
2312                         memLimit = 0;
2313                         reportPackage = null;
2314                     }
2315                 }
2316                 if (procName == null) {
2317                     return;
2318                 }
2319
2320                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2321                         "Showing dump heap notification from " + procName + "/" + uid);
2322
2323                 INotificationManager inm = NotificationManager.getService();
2324                 if (inm == null) {
2325                     return;
2326                 }
2327
2328                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2329
2330
2331                 Intent deleteIntent = new Intent();
2332                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2333                 Intent intent = new Intent();
2334                 intent.setClassName("android", DumpHeapActivity.class.getName());
2335                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2336                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2337                 if (reportPackage != null) {
2338                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2339                 }
2340                 int userId = UserHandle.getUserId(uid);
2341                 Notification notification =
2342                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2343                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2344                         .setWhen(0)
2345                         .setOngoing(true)
2346                         .setAutoCancel(true)
2347                         .setTicker(text)
2348                         .setColor(mContext.getColor(
2349                                 com.android.internal.R.color.system_notification_accent_color))
2350                         .setContentTitle(text)
2351                         .setContentText(
2352                                 mContext.getText(R.string.dump_heap_notification_detail))
2353                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2354                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2355                                 new UserHandle(userId)))
2356                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2357                                 deleteIntent, 0, UserHandle.SYSTEM))
2358                         .build();
2359
2360                 try {
2361                     inm.enqueueNotificationWithTag("android", "android", null,
2362                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2363                             notification, userId);
2364                 } catch (RuntimeException e) {
2365                     Slog.w(ActivityManagerService.TAG,
2366                             "Error showing notification for dump heap", e);
2367                 } catch (RemoteException e) {
2368                 }
2369             } break;
2370             case DELETE_DUMPHEAP_MSG: {
2371                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2372                         null, DumpHeapActivity.JAVA_URI,
2373                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2374                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2375                         UserHandle.myUserId());
2376                 synchronized (ActivityManagerService.this) {
2377                     mMemWatchDumpFile = null;
2378                     mMemWatchDumpProcName = null;
2379                     mMemWatchDumpPid = -1;
2380                     mMemWatchDumpUid = -1;
2381                 }
2382             } break;
2383             case FOREGROUND_PROFILE_CHANGED_MSG: {
2384                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2385             } break;
2386             case REPORT_TIME_TRACKER_MSG: {
2387                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2388                 tracker.deliverResult(mContext);
2389             } break;
2390             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2391                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2392             } break;
2393             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2394                 mUserController.dispatchLockedBootComplete(msg.arg1);
2395             } break;
2396             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2397                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2398                 try {
2399                     connection.shutdown();
2400                 } catch (RemoteException e) {
2401                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2402                 }
2403                 // Only a UiAutomation can set this flag and now that
2404                 // it is finished we make sure it is reset to its default.
2405                 mUserIsMonkey = false;
2406             } break;
2407             case IDLE_UIDS_MSG: {
2408                 idleUids();
2409             } break;
2410             case VR_MODE_CHANGE_MSG: {
2411                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2412                     return;
2413                 }
2414                 synchronized (ActivityManagerService.this) {
2415                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2416                     mWindowManager.disableNonVrUi(disableNonVrUi);
2417                     if (disableNonVrUi) {
2418                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2419                         // then remove the pinned stack.
2420                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2421                                 PINNED_STACK_ID);
2422                         if (pinnedStack != null) {
2423                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2424                         }
2425                     }
2426                 }
2427             } break;
2428             case DISPATCH_SCREEN_AWAKE_MSG: {
2429                 final boolean isAwake = msg.arg1 != 0;
2430                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2431                     mScreenObservers.get(i).onAwakeStateChanged(isAwake);
2432                 }
2433             } break;
2434             case DISPATCH_SCREEN_KEYGUARD_MSG: {
2435                 final boolean isShowing = msg.arg1 != 0;
2436                 for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
2437                     mScreenObservers.get(i).onKeyguardStateChanged(isShowing);
2438                 }
2439             } break;
2440             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2441                 synchronized (ActivityManagerService.this) {
2442                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2443                         ProcessRecord r = mLruProcesses.get(i);
2444                         if (r.thread != null) {
2445                             try {
2446                                 r.thread.handleTrustStorageUpdate();
2447                             } catch (RemoteException ex) {
2448                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2449                                         r.info.processName);
2450                             }
2451                         }
2452                     }
2453                 }
2454             } break;
2455             }
2456         }
2457     };
2458
2459     static final int COLLECT_PSS_BG_MSG = 1;
2460
2461     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2462         @Override
2463         public void handleMessage(Message msg) {
2464             switch (msg.what) {
2465             case COLLECT_PSS_BG_MSG: {
2466                 long start = SystemClock.uptimeMillis();
2467                 MemInfoReader memInfo = null;
2468                 synchronized (ActivityManagerService.this) {
2469                     if (mFullPssPending) {
2470                         mFullPssPending = false;
2471                         memInfo = new MemInfoReader();
2472                     }
2473                 }
2474                 if (memInfo != null) {
2475                     updateCpuStatsNow();
2476                     long nativeTotalPss = 0;
2477                     final List<ProcessCpuTracker.Stats> stats;
2478                     synchronized (mProcessCpuTracker) {
2479                         stats = mProcessCpuTracker.getStats( (st)-> {
2480                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2481                         });
2482                     }
2483                     final int N = stats.size();
2484                     for (int j = 0; j < N; j++) {
2485                         synchronized (mPidsSelfLocked) {
2486                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2487                                 // This is one of our own processes; skip it.
2488                                 continue;
2489                             }
2490                         }
2491                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2492                     }
2493                     memInfo.readMemInfo();
2494                     synchronized (ActivityManagerService.this) {
2495                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2496                                 + (SystemClock.uptimeMillis()-start) + "ms");
2497                         final long cachedKb = memInfo.getCachedSizeKb();
2498                         final long freeKb = memInfo.getFreeSizeKb();
2499                         final long zramKb = memInfo.getZramTotalSizeKb();
2500                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2501                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2502                                 kernelKb*1024, nativeTotalPss*1024);
2503                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2504                                 nativeTotalPss);
2505                     }
2506                 }
2507
2508                 int num = 0;
2509                 long[] tmp = new long[2];
2510                 do {
2511                     ProcessRecord proc;
2512                     int procState;
2513                     int pid;
2514                     long lastPssTime;
2515                     synchronized (ActivityManagerService.this) {
2516                         if (mPendingPssProcesses.size() <= 0) {
2517                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2518                                     "Collected PSS of " + num + " processes in "
2519                                     + (SystemClock.uptimeMillis() - start) + "ms");
2520                             mPendingPssProcesses.clear();
2521                             return;
2522                         }
2523                         proc = mPendingPssProcesses.remove(0);
2524                         procState = proc.pssProcState;
2525                         lastPssTime = proc.lastPssTime;
2526                         if (proc.thread != null && procState == proc.setProcState
2527                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2528                                         < SystemClock.uptimeMillis()) {
2529                             pid = proc.pid;
2530                         } else {
2531                             proc = null;
2532                             pid = 0;
2533                         }
2534                     }
2535                     if (proc != null) {
2536                         long pss = Debug.getPss(pid, tmp, null);
2537                         synchronized (ActivityManagerService.this) {
2538                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2539                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2540                                 num++;
2541                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2542                                         SystemClock.uptimeMillis());
2543                             }
2544                         }
2545                     }
2546                 } while (true);
2547             }
2548             }
2549         }
2550     };
2551
2552     public void setSystemProcess() {
2553         try {
2554             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2555             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2556             ServiceManager.addService("meminfo", new MemBinder(this));
2557             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2558             ServiceManager.addService("dbinfo", new DbBinder(this));
2559             if (MONITOR_CPU_USAGE) {
2560                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2561             }
2562             ServiceManager.addService("permission", new PermissionController(this));
2563             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2564
2565             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2566                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2567             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2568
2569             synchronized (this) {
2570                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2571                 app.persistent = true;
2572                 app.pid = MY_PID;
2573                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2574                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2575                 synchronized (mPidsSelfLocked) {
2576                     mPidsSelfLocked.put(app.pid, app);
2577                 }
2578                 updateLruProcessLocked(app, false, null);
2579                 updateOomAdjLocked();
2580             }
2581         } catch (PackageManager.NameNotFoundException e) {
2582             throw new RuntimeException(
2583                     "Unable to find android system package", e);
2584         }
2585     }
2586
2587     public void setWindowManager(WindowManagerService wm) {
2588         mWindowManager = wm;
2589         mStackSupervisor.setWindowManager(wm);
2590         mActivityStarter.setWindowManager(wm);
2591     }
2592
2593     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2594         mUsageStatsService = usageStatsManager;
2595     }
2596
2597     public void startObservingNativeCrashes() {
2598         final NativeCrashListener ncl = new NativeCrashListener(this);
2599         ncl.start();
2600     }
2601
2602     public IAppOpsService getAppOpsService() {
2603         return mAppOpsService;
2604     }
2605
2606     static class MemBinder extends Binder {
2607         ActivityManagerService mActivityManagerService;
2608         MemBinder(ActivityManagerService activityManagerService) {
2609             mActivityManagerService = activityManagerService;
2610         }
2611
2612         @Override
2613         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2614             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2615                     "meminfo", pw)) return;
2616             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2617         }
2618     }
2619
2620     static class GraphicsBinder extends Binder {
2621         ActivityManagerService mActivityManagerService;
2622         GraphicsBinder(ActivityManagerService activityManagerService) {
2623             mActivityManagerService = activityManagerService;
2624         }
2625
2626         @Override
2627         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2628             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2629                     "gfxinfo", pw)) return;
2630             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2631         }
2632     }
2633
2634     static class DbBinder extends Binder {
2635         ActivityManagerService mActivityManagerService;
2636         DbBinder(ActivityManagerService activityManagerService) {
2637             mActivityManagerService = activityManagerService;
2638         }
2639
2640         @Override
2641         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2642             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2643                     "dbinfo", pw)) return;
2644             mActivityManagerService.dumpDbInfo(fd, pw, args);
2645         }
2646     }
2647
2648     static class CpuBinder extends Binder {
2649         ActivityManagerService mActivityManagerService;
2650         CpuBinder(ActivityManagerService activityManagerService) {
2651             mActivityManagerService = activityManagerService;
2652         }
2653
2654         @Override
2655         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2656             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2657                     "cpuinfo", pw)) return;
2658             synchronized (mActivityManagerService.mProcessCpuTracker) {
2659                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2660                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2661                         SystemClock.uptimeMillis()));
2662             }
2663         }
2664     }
2665
2666     public static final class Lifecycle extends SystemService {
2667         private final ActivityManagerService mService;
2668
2669         public Lifecycle(Context context) {
2670             super(context);
2671             mService = new ActivityManagerService(context);
2672         }
2673
2674         @Override
2675         public void onStart() {
2676             mService.start();
2677         }
2678
2679         @Override
2680         public void onCleanupUser(int userId) {
2681             mService.mBatteryStatsService.onCleanupUser(userId);
2682         }
2683
2684         public ActivityManagerService getService() {
2685             return mService;
2686         }
2687     }
2688
2689     @VisibleForTesting
2690     public ActivityManagerService(Injector injector) {
2691         mInjector = injector;
2692         mContext = mInjector.getContext();
2693         mUiContext = null;
2694         GL_ES_VERSION = 0;
2695         mActivityStarter = null;
2696         mAppErrors = null;
2697         mAppOpsService = mInjector.getAppOpsService(null, null);
2698         mBatteryStatsService = null;
2699         mCompatModePackages = null;
2700         mConstants = null;
2701         mGrantFile = null;
2702         mHandler = null;
2703         mHandlerThread = null;
2704         mIntentFirewall = null;
2705         mKeyguardController = null;
2706         mPermissionReviewRequired = false;
2707         mProcessCpuThread = null;
2708         mProcessStats = null;
2709         mProviderMap = null;
2710         mRecentTasks = null;
2711         mServices = null;
2712         mStackSupervisor = null;
2713         mSystemThread = null;
2714         mTaskChangeNotificationController = null;
2715         mUiHandler = injector.getUiHandler(null);
2716         mUserController = null;
2717         mVrController = null;
2718     }
2719
2720     // Note: This method is invoked on the main thread but may need to attach various
2721     // handlers to other threads.  So take care to be explicit about the looper.
2722     public ActivityManagerService(Context systemContext) {
2723         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2724         mInjector = new Injector();
2725         mContext = systemContext;
2726
2727         mFactoryTest = FactoryTest.getMode();
2728         mSystemThread = ActivityThread.currentActivityThread();
2729         mUiContext = mSystemThread.getSystemUiContext();
2730
2731         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2732
2733         mPermissionReviewRequired = mContext.getResources().getBoolean(
2734                 com.android.internal.R.bool.config_permissionReviewRequired);
2735
2736         mHandlerThread = new ServiceThread(TAG,
2737                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2738         mHandlerThread.start();
2739         mHandler = new MainHandler(mHandlerThread.getLooper());
2740         mUiHandler = mInjector.getUiHandler(this);
2741
2742         mConstants = new ActivityManagerConstants(this, mHandler);
2743
2744         /* static; one-time init here */
2745         if (sKillHandler == null) {
2746             sKillThread = new ServiceThread(TAG + ":kill",
2747                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2748             sKillThread.start();
2749             sKillHandler = new KillHandler(sKillThread.getLooper());
2750         }
2751
2752         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2753                 "foreground", BROADCAST_FG_TIMEOUT, false);
2754         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2755                 "background", BROADCAST_BG_TIMEOUT, true);
2756         mBroadcastQueues[0] = mFgBroadcastQueue;
2757         mBroadcastQueues[1] = mBgBroadcastQueue;
2758
2759         mServices = new ActiveServices(this);
2760         mProviderMap = new ProviderMap(this);
2761         mAppErrors = new AppErrors(mUiContext, this);
2762
2763         // TODO: Move creation of battery stats service outside of activity manager service.
2764         File dataDir = Environment.getDataDirectory();
2765         File systemDir = new File(dataDir, "system");
2766         systemDir.mkdirs();
2767         mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2768         mBatteryStatsService.getActiveStatistics().readLocked();
2769         mBatteryStatsService.scheduleWriteToDisk();
2770         mOnBattery = DEBUG_POWER ? true
2771                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2772         mBatteryStatsService.getActiveStatistics().setCallback(this);
2773
2774         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2775
2776         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2777         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2778                 new IAppOpsCallback.Stub() {
2779                     @Override public void opChanged(int op, int uid, String packageName) {
2780                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2781                             if (mAppOpsService.checkOperation(op, uid, packageName)
2782                                     != AppOpsManager.MODE_ALLOWED) {
2783                                 runInBackgroundDisabled(uid);
2784                             }
2785                         }
2786                     }
2787                 });
2788
2789         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2790
2791         mUserController = new UserController(this);
2792
2793         mVrController = new VrController(this);
2794
2795         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2796             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2797
2798         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2799             mUseFifoUiScheduling = true;
2800         }
2801
2802         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2803         mTempConfig.setToDefaults();
2804         mTempConfig.setLocales(LocaleList.getDefault());
2805         mConfigurationSeq = mTempConfig.seq = 1;
2806         mStackSupervisor = createStackSupervisor();
2807         mStackSupervisor.onConfigurationChanged(mTempConfig);
2808         mKeyguardController = mStackSupervisor.mKeyguardController;
2809         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2810         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2811         mTaskChangeNotificationController =
2812                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2813         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2814         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2815
2816         mProcessCpuThread = new Thread("CpuTracker") {
2817             @Override
2818             public void run() {
2819                 synchronized (mProcessCpuTracker) {
2820                     mProcessCpuInitLatch.countDown();
2821                     mProcessCpuTracker.init();
2822                 }
2823                 while (true) {
2824                     try {
2825                         try {
2826                             synchronized(this) {
2827                                 final long now = SystemClock.uptimeMillis();
2828                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2829                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2830                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2831                                 //        + ", write delay=" + nextWriteDelay);
2832                                 if (nextWriteDelay < nextCpuDelay) {
2833                                     nextCpuDelay = nextWriteDelay;
2834                                 }
2835                                 if (nextCpuDelay > 0) {
2836                                     mProcessCpuMutexFree.set(true);
2837                                     this.wait(nextCpuDelay);
2838                                 }
2839                             }
2840                         } catch (InterruptedException e) {
2841                         }
2842                         updateCpuStatsNow();
2843                     } catch (Exception e) {
2844                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2845                     }
2846                 }
2847             }
2848         };
2849
2850         Watchdog.getInstance().addMonitor(this);
2851         Watchdog.getInstance().addThread(mHandler);
2852     }
2853
2854     protected ActivityStackSupervisor createStackSupervisor() {
2855         return new ActivityStackSupervisor(this, mHandler.getLooper());
2856     }
2857
2858     public void setSystemServiceManager(SystemServiceManager mgr) {
2859         mSystemServiceManager = mgr;
2860     }
2861
2862     public void setInstaller(Installer installer) {
2863         mInstaller = installer;
2864     }
2865
2866     private void start() {
2867         removeAllProcessGroups();
2868         mProcessCpuThread.start();
2869
2870         mBatteryStatsService.publish();
2871         mAppOpsService.publish(mContext);
2872         Slog.d("AppOps", "AppOpsService published");
2873         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2874         // Wait for the synchronized block started in mProcessCpuThread,
2875         // so that any other acccess to mProcessCpuTracker from main thread
2876         // will be blocked during mProcessCpuTracker initialization.
2877         try {
2878             mProcessCpuInitLatch.await();
2879         } catch (InterruptedException e) {
2880             Slog.wtf(TAG, "Interrupted wait during start", e);
2881             Thread.currentThread().interrupt();
2882             throw new IllegalStateException("Interrupted wait during start");
2883         }
2884     }
2885
2886     void onUserStoppedLocked(int userId) {
2887         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2888     }
2889
2890     public void initPowerManagement() {
2891         mStackSupervisor.initPowerManagement();
2892         mBatteryStatsService.initPowerManagement();
2893         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2894         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2895         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2896         mVoiceWakeLock.setReferenceCounted(false);
2897     }
2898
2899     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2900         if (mBackgroundLaunchBroadcasts == null) {
2901             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2902         }
2903         return mBackgroundLaunchBroadcasts;
2904     }
2905
2906     @Override
2907     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2908             throws RemoteException {
2909         if (code == SYSPROPS_TRANSACTION) {
2910             // We need to tell all apps about the system property change.
2911             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2912             synchronized(this) {
2913                 final int NP = mProcessNames.getMap().size();
2914                 for (int ip=0; ip<NP; ip++) {
2915                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2916                     final int NA = apps.size();
2917                     for (int ia=0; ia<NA; ia++) {
2918                         ProcessRecord app = apps.valueAt(ia);
2919                         if (app.thread != null) {
2920                             procs.add(app.thread.asBinder());
2921                         }
2922                     }
2923                 }
2924             }
2925
2926             int N = procs.size();
2927             for (int i=0; i<N; i++) {
2928                 Parcel data2 = Parcel.obtain();
2929                 try {
2930                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2931                             Binder.FLAG_ONEWAY);
2932                 } catch (RemoteException e) {
2933                 }
2934                 data2.recycle();
2935             }
2936         }
2937         try {
2938             return super.onTransact(code, data, reply, flags);
2939         } catch (RuntimeException e) {
2940             // The activity manager only throws security exceptions, so let's
2941             // log all others.
2942             if (!(e instanceof SecurityException)) {
2943                 Slog.wtf(TAG, "Activity Manager Crash."
2944                         + " UID:" + Binder.getCallingUid()
2945                         + " PID:" + Binder.getCallingPid()
2946                         + " TRANS:" + code, e);
2947             }
2948             throw e;
2949         }
2950     }
2951
2952     void updateCpuStats() {
2953         final long now = SystemClock.uptimeMillis();
2954         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2955             return;
2956         }
2957         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2958             synchronized (mProcessCpuThread) {
2959                 mProcessCpuThread.notify();
2960             }
2961         }
2962     }
2963
2964     void updateCpuStatsNow() {
2965         synchronized (mProcessCpuTracker) {
2966             mProcessCpuMutexFree.set(false);
2967             final long now = SystemClock.uptimeMillis();
2968             boolean haveNewCpuStats = false;
2969
2970             if (MONITOR_CPU_USAGE &&
2971                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2972                 mLastCpuTime.set(now);
2973                 mProcessCpuTracker.update();
2974                 if (mProcessCpuTracker.hasGoodLastStats()) {
2975                     haveNewCpuStats = true;
2976                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2977                     //Slog.i(TAG, "Total CPU usage: "
2978                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2979
2980                     // Slog the cpu usage if the property is set.
2981                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2982                         int user = mProcessCpuTracker.getLastUserTime();
2983                         int system = mProcessCpuTracker.getLastSystemTime();
2984                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2985                         int irq = mProcessCpuTracker.getLastIrqTime();
2986                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2987                         int idle = mProcessCpuTracker.getLastIdleTime();
2988
2989                         int total = user + system + iowait + irq + softIrq + idle;
2990                         if (total == 0) total = 1;
2991
2992                         EventLog.writeEvent(EventLogTags.CPU,
2993                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2994                                 (user * 100) / total,
2995                                 (system * 100) / total,
2996                                 (iowait * 100) / total,
2997                                 (irq * 100) / total,
2998                                 (softIrq * 100) / total);
2999                     }
3000                 }
3001             }
3002
3003             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
3004             synchronized(bstats) {
3005                 synchronized(mPidsSelfLocked) {
3006                     if (haveNewCpuStats) {
3007                         if (bstats.startAddingCpuLocked()) {
3008                             int totalUTime = 0;
3009                             int totalSTime = 0;
3010                             final int N = mProcessCpuTracker.countStats();
3011                             for (int i=0; i<N; i++) {
3012                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
3013                                 if (!st.working) {
3014                                     continue;
3015                                 }
3016                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
3017                                 totalUTime += st.rel_utime;
3018                                 totalSTime += st.rel_stime;
3019                                 if (pr != null) {
3020                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3021                                     if (ps == null || !ps.isActive()) {
3022                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3023                                                 pr.info.uid, pr.processName);
3024                                     }
3025                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3026                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3027                                     if (pr.lastCpuTime == 0) {
3028                                         pr.lastCpuTime = pr.curCpuTime;
3029                                     }
3030                                 } else {
3031                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3032                                     if (ps == null || !ps.isActive()) {
3033                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3034                                                 bstats.mapUid(st.uid), st.name);
3035                                     }
3036                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3037                                 }
3038                             }
3039                             final int userTime = mProcessCpuTracker.getLastUserTime();
3040                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3041                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3042                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3043                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3044                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3045                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3046                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3047                         }
3048                     }
3049                 }
3050
3051                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3052                     mLastWriteTime = now;
3053                     mBatteryStatsService.scheduleWriteToDisk();
3054                 }
3055             }
3056         }
3057     }
3058
3059     @Override
3060     public void batteryNeedsCpuUpdate() {
3061         updateCpuStatsNow();
3062     }
3063
3064     @Override
3065     public void batteryPowerChanged(boolean onBattery) {
3066         // When plugging in, update the CPU stats first before changing
3067         // the plug state.
3068         updateCpuStatsNow();
3069         synchronized (this) {
3070             synchronized(mPidsSelfLocked) {
3071                 mOnBattery = DEBUG_POWER ? true : onBattery;
3072             }
3073         }
3074     }
3075
3076     @Override
3077     public void batterySendBroadcast(Intent intent) {
3078         synchronized (this) {
3079             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3080                     AppOpsManager.OP_NONE, null, false, false,
3081                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3082         }
3083     }
3084
3085     /**
3086      * Initialize the application bind args. These are passed to each
3087      * process when the bindApplication() IPC is sent to the process. They're
3088      * lazily setup to make sure the services are running when they're asked for.
3089      */
3090     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3091         // Isolated processes won't get this optimization, so that we don't
3092         // violate the rules about which services they have access to.
3093         if (isolated) {
3094             if (mIsolatedAppBindArgs == null) {
3095                 mIsolatedAppBindArgs = new HashMap<>();
3096                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3097             }
3098             return mIsolatedAppBindArgs;
3099         }
3100
3101         if (mAppBindArgs == null) {
3102             mAppBindArgs = new HashMap<>();
3103
3104             // Setup the application init args
3105             mAppBindArgs.put("package", ServiceManager.getService("package"));
3106             mAppBindArgs.put("window", ServiceManager.getService("window"));
3107             mAppBindArgs.put(Context.ALARM_SERVICE,
3108                     ServiceManager.getService(Context.ALARM_SERVICE));
3109         }
3110         return mAppBindArgs;
3111     }
3112
3113     /**
3114      * Update AMS states when an activity is resumed. This should only be called by
3115      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3116      */
3117     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3118         final TaskRecord task = r.getTask();
3119         if (task.isApplicationTask()) {
3120             if (mCurAppTimeTracker != r.appTimeTracker) {
3121                 // We are switching app tracking.  Complete the current one.
3122                 if (mCurAppTimeTracker != null) {
3123                     mCurAppTimeTracker.stop();
3124                     mHandler.obtainMessage(
3125                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3126                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3127                     mCurAppTimeTracker = null;
3128                 }
3129                 if (r.appTimeTracker != null) {
3130                     mCurAppTimeTracker = r.appTimeTracker;
3131                     startTimeTrackingFocusedActivityLocked();
3132                 }
3133             } else {
3134                 startTimeTrackingFocusedActivityLocked();
3135             }
3136         } else {
3137             r.appTimeTracker = null;
3138         }
3139         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3140         // TODO: Probably not, because we don't want to resume voice on switching
3141         // back to this activity
3142         if (task.voiceInteractor != null) {
3143             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3144         } else {
3145             finishRunningVoiceLocked();
3146
3147             if (mLastResumedActivity != null) {
3148                 final IVoiceInteractionSession session;
3149
3150                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3151                 if (lastResumedActivityTask != null
3152                         && lastResumedActivityTask.voiceSession != null) {
3153                     session = lastResumedActivityTask.voiceSession;
3154                 } else {
3155                     session = mLastResumedActivity.voiceSession;
3156                 }
3157
3158                 if (session != null) {
3159                     // We had been in a voice interaction session, but now focused has
3160                     // move to something different.  Just finish the session, we can't
3161                     // return to it and retain the proper state and synchronization with
3162                     // the voice interaction service.
3163                     finishVoiceTask(session);
3164                 }
3165             }
3166         }
3167
3168         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3169             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3170             mHandler.obtainMessage(
3171                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3172         }
3173         mLastResumedActivity = r;
3174
3175         mWindowManager.setFocusedApp(r.appToken, true);
3176
3177         applyUpdateLockStateLocked(r);
3178         applyUpdateVrModeLocked(r);
3179
3180         EventLogTags.writeAmSetResumedActivity(
3181                 r == null ? -1 : r.userId,
3182                 r == null ? "NULL" : r.shortComponentName,
3183                 reason);
3184     }
3185
3186     @Override
3187     public void setFocusedStack(int stackId) {
3188         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3189         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3190         final long callingId = Binder.clearCallingIdentity();
3191         try {
3192             synchronized (this) {
3193                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3194                 if (stack == null) {
3195                     return;
3196                 }
3197                 final ActivityRecord r = stack.topRunningActivityLocked();
3198                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3199                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3200                 }
3201             }
3202         } finally {
3203             Binder.restoreCallingIdentity(callingId);
3204         }
3205     }
3206
3207     @Override
3208     public void setFocusedTask(int taskId) {
3209         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3210         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3211         final long callingId = Binder.clearCallingIdentity();
3212         try {
3213             synchronized (this) {
3214                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3215                 if (task == null) {
3216                     return;
3217                 }
3218                 final ActivityRecord r = task.topRunningActivityLocked();
3219                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3220                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3221                 }
3222             }
3223         } finally {
3224             Binder.restoreCallingIdentity(callingId);
3225         }
3226     }
3227
3228     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3229     @Override
3230     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3231         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3232         mTaskChangeNotificationController.registerTaskStackListener(listener);
3233     }
3234
3235     /**
3236      * Unregister a task stack listener so that it stops receiving callbacks.
3237      */
3238     @Override
3239     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3240          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3241          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3242      }
3243
3244     @Override
3245     public void notifyActivityDrawn(IBinder token) {
3246         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3247         synchronized (this) {
3248             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3249             if (r != null) {
3250                 r.getStack().notifyActivityDrawnLocked(r);
3251             }
3252         }
3253     }
3254
3255     final void applyUpdateLockStateLocked(ActivityRecord r) {
3256         // Modifications to the UpdateLock state are done on our handler, outside
3257         // the activity manager's locks.  The new state is determined based on the
3258         // state *now* of the relevant activity record.  The object is passed to
3259         // the handler solely for logging detail, not to be consulted/modified.
3260         final boolean nextState = r != null && r.immersive;
3261         mHandler.sendMessage(
3262                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3263     }
3264
3265     final void applyUpdateVrModeLocked(ActivityRecord r) {
3266         // VR apps are expected to run in a main display. If an app is turning on VR for
3267         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3268         // fullscreen stack before enabling VR Mode.
3269         // TODO: The goal of this code is to keep the VR app on the main display. When the
3270         // stack implementation changes in the future, keep in mind that the use of the fullscreen
3271         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3272         // option would be a better choice here.
3273         if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3274             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3275                     + " to main stack for VR");
3276             moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3277         }
3278         mHandler.sendMessage(
3279                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3280     }
3281
3282     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3283         Message msg = Message.obtain();
3284         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3285         msg.obj = r.getTask().askedCompatMode ? null : r;
3286         mUiHandler.sendMessage(msg);
3287     }
3288
3289     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3290         final Configuration globalConfig = getGlobalConfiguration();
3291         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3292                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3293             final Message msg = Message.obtain();
3294             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3295             msg.obj = r;
3296             mUiHandler.sendMessage(msg);
3297         }
3298     }
3299
3300     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3301             String what, Object obj, ProcessRecord srcApp) {
3302         app.lastActivityTime = now;
3303
3304         if (app.activities.size() > 0) {
3305             // Don't want to touch dependent processes that are hosting activities.
3306             return index;
3307         }
3308
3309         int lrui = mLruProcesses.lastIndexOf(app);
3310         if (lrui < 0) {
3311             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3312                     + what + " " + obj + " from " + srcApp);
3313             return index;
3314         }
3315
3316         if (lrui >= index) {
3317             // Don't want to cause this to move dependent processes *back* in the
3318             // list as if they were less frequently used.
3319             return index;
3320         }
3321
3322         if (lrui >= mLruProcessActivityStart) {
3323             // Don't want to touch dependent processes that are hosting activities.
3324             return index;
3325         }
3326
3327         mLruProcesses.remove(lrui);
3328         if (index > 0) {
3329             index--;
3330         }
3331         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3332                 + " in LRU list: " + app);
3333         mLruProcesses.add(index, app);
3334         return index;
3335     }
3336
3337     static void killProcessGroup(int uid, int pid) {
3338         if (sKillHandler != null) {
3339             sKillHandler.sendMessage(
3340                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3341         } else {
3342             Slog.w(TAG, "Asked to kill process group before system bringup!");
3343             Process.killProcessGroup(uid, pid);
3344         }
3345     }
3346
3347     final void removeLruProcessLocked(ProcessRecord app) {
3348         int lrui = mLruProcesses.lastIndexOf(app);
3349         if (lrui >= 0) {
3350             if (!app.killed) {
3351                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3352                 killProcessQuiet(app.pid);
3353                 killProcessGroup(app.uid, app.pid);
3354             }
3355             if (lrui <= mLruProcessActivityStart) {
3356                 mLruProcessActivityStart--;
3357             }
3358             if (lrui <= mLruProcessServiceStart) {
3359                 mLruProcessServiceStart--;
3360             }
3361             mLruProcesses.remove(lrui);
3362         }
3363     }
3364
3365     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3366             ProcessRecord client) {
3367         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3368                 || app.treatLikeActivity;
3369         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3370         if (!activityChange && hasActivity) {
3371             // The process has activities, so we are only allowing activity-based adjustments
3372             // to move it.  It should be kept in the front of the list with other
3373             // processes that have activities, and we don't want those to change their
3374             // order except due to activity operations.
3375             return;
3376         }
3377
3378         mLruSeq++;
3379         final long now = SystemClock.uptimeMillis();
3380         app.lastActivityTime = now;
3381
3382         // First a quick reject: if the app is already at the position we will
3383         // put it, then there is nothing to do.
3384         if (hasActivity) {
3385             final int N = mLruProcesses.size();
3386             if (N > 0 && mLruProcesses.get(N-1) == app) {
3387                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3388                 return;
3389             }
3390         } else {
3391             if (mLruProcessServiceStart > 0
3392                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3393                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3394                 return;
3395             }
3396         }
3397
3398         int lrui = mLruProcesses.lastIndexOf(app);
3399
3400         if (app.persistent && lrui >= 0) {
3401             // We don't care about the position of persistent processes, as long as
3402             // they are in the list.
3403             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3404             return;
3405         }
3406
3407         /* In progress: compute new position first, so we can avoid doing work
3408            if the process is not actually going to move.  Not yet working.
3409         int addIndex;
3410         int nextIndex;
3411         boolean inActivity = false, inService = false;
3412         if (hasActivity) {
3413             // Process has activities, put it at the very tipsy-top.
3414             addIndex = mLruProcesses.size();
3415             nextIndex = mLruProcessServiceStart;
3416             inActivity = true;
3417         } else if (hasService) {
3418             // Process has services, put it at the top of the service list.
3419             addIndex = mLruProcessActivityStart;
3420             nextIndex = mLruProcessServiceStart;
3421             inActivity = true;
3422             inService = true;
3423         } else  {
3424             // Process not otherwise of interest, it goes to the top of the non-service area.
3425             addIndex = mLruProcessServiceStart;
3426             if (client != null) {
3427                 int clientIndex = mLruProcesses.lastIndexOf(client);
3428                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3429                         + app);
3430                 if (clientIndex >= 0 && addIndex > clientIndex) {
3431                     addIndex = clientIndex;
3432                 }
3433             }
3434             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3435         }
3436
3437         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3438                 + mLruProcessActivityStart + "): " + app);
3439         */
3440
3441         if (lrui >= 0) {
3442             if (lrui < mLruProcessActivityStart) {
3443                 mLruProcessActivityStart--;
3444             }
3445             if (lrui < mLruProcessServiceStart) {
3446                 mLruProcessServiceStart--;
3447             }
3448             /*
3449             if (addIndex > lrui) {
3450                 addIndex--;
3451             }
3452             if (nextIndex > lrui) {
3453                 nextIndex--;
3454             }
3455             */
3456             mLruProcesses.remove(lrui);
3457         }
3458
3459         /*
3460         mLruProcesses.add(addIndex, app);
3461         if (inActivity) {
3462             mLruProcessActivityStart++;
3463         }
3464         if (inService) {
3465             mLruProcessActivityStart++;
3466         }
3467         */
3468
3469         int nextIndex;
3470         if (hasActivity) {
3471             final int N = mLruProcesses.size();
3472             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3473                 // Process doesn't have activities, but has clients with
3474                 // activities...  move it up, but one below the top (the top
3475                 // should always have a real activity).
3476                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3477                         "Adding to second-top of LRU activity list: " + app);
3478                 mLruProcesses.add(N - 1, app);
3479                 // To keep it from spamming the LRU list (by making a bunch of clients),
3480                 // we will push down any other entries owned by the app.
3481                 final int uid = app.info.uid;
3482                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3483                     ProcessRecord subProc = mLruProcesses.get(i);
3484                     if (subProc.info.uid == uid) {
3485                         // We want to push this one down the list.  If the process after
3486                         // it is for the same uid, however, don't do so, because we don't
3487                         // want them internally to be re-ordered.
3488                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3489                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3490                                     "Pushing uid " + uid + " swapping at " + i + ": "
3491                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3492                             ProcessRecord tmp = mLruProcesses.get(i);
3493                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3494                             mLruProcesses.set(i - 1, tmp);
3495                             i--;
3496                         }
3497                     } else {
3498                         // A gap, we can stop here.
3499                         break;
3500                     }
3501                 }
3502             } else {
3503                 // Process has activities, put it at the very tipsy-top.
3504                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3505                 mLruProcesses.add(app);
3506             }
3507             nextIndex = mLruProcessServiceStart;
3508         } else if (hasService) {
3509             // Process has services, put it at the top of the service list.
3510             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3511             mLruProcesses.add(mLruProcessActivityStart, app);
3512             nextIndex = mLruProcessServiceStart;
3513             mLruProcessActivityStart++;
3514         } else  {
3515             // Process not otherwise of interest, it goes to the top of the non-service area.
3516             int index = mLruProcessServiceStart;
3517             if (client != null) {
3518                 // If there is a client, don't allow the process to be moved up higher
3519                 // in the list than that client.
3520                 int clientIndex = mLruProcesses.lastIndexOf(client);
3521                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3522                         + " when updating " + app);
3523                 if (clientIndex <= lrui) {
3524                     // Don't allow the client index restriction to push it down farther in the
3525                     // list than it already is.
3526                     clientIndex = lrui;
3527                 }
3528                 if (clientIndex >= 0 && index > clientIndex) {
3529                     index = clientIndex;
3530                 }
3531             }
3532             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3533             mLruProcesses.add(index, app);
3534             nextIndex = index-1;
3535             mLruProcessActivityStart++;
3536             mLruProcessServiceStart++;
3537         }
3538
3539         // If the app is currently using a content provider or service,
3540         // bump those processes as well.
3541         for (int j=app.connections.size()-1; j>=0; j--) {
3542             ConnectionRecord cr = app.connections.valueAt(j);
3543             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3544                     && cr.binding.service.app != null
3545                     && cr.binding.service.app.lruSeq != mLruSeq
3546                     && !cr.binding.service.app.persistent) {
3547                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3548                         "service connection", cr, app);
3549             }
3550         }
3551         for (int j=app.conProviders.size()-1; j>=0; j--) {
3552             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3553             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3554                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3555                         "provider reference", cpr, app);
3556             }
3557         }
3558     }
3559
3560     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3561         if (uid == SYSTEM_UID) {
3562             // The system gets to run in any process.  If there are multiple
3563             // processes with the same uid, just pick the first (this
3564             // should never happen).
3565             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3566             if (procs == null) return null;
3567             final int procCount = procs.size();
3568             for (int i = 0; i < procCount; i++) {
3569                 final int procUid = procs.keyAt(i);
3570                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3571                     // Don't use an app process or different user process for system component.
3572                     continue;
3573                 }
3574                 return procs.valueAt(i);
3575             }
3576         }
3577         ProcessRecord proc = mProcessNames.get(processName, uid);
3578         if (false && proc != null && !keepIfLarge
3579                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3580                 && proc.lastCachedPss >= 4000) {
3581             // Turn this condition on to cause killing to happen regularly, for testing.
3582             if (proc.baseProcessTracker != null) {
3583                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3584             }
3585             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3586         } else if (proc != null && !keepIfLarge
3587                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3588                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3589             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3590             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3591                 if (proc.baseProcessTracker != null) {
3592                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3593                 }
3594                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3595             }
3596         }
3597         return proc;
3598     }
3599
3600     void notifyPackageUse(String packageName, int reason) {
3601         synchronized(this) {
3602             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3603         }
3604     }
3605
3606     boolean isNextTransitionForward() {
3607         int transit = mWindowManager.getPendingAppTransition();
3608         return transit == TRANSIT_ACTIVITY_OPEN
3609                 || transit == TRANSIT_TASK_OPEN
3610                 || transit == TRANSIT_TASK_TO_FRONT;
3611     }
3612
3613     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3614             String processName, String abiOverride, int uid, Runnable crashHandler) {
3615         synchronized(this) {
3616             ApplicationInfo info = new ApplicationInfo();
3617             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3618             // For isolated processes, the former contains the parent's uid and the latter the
3619             // actual uid of the isolated process.
3620             // In the special case introduced by this method (which is, starting an isolated
3621             // process directly from the SystemServer without an actual parent app process) the
3622             // closest thing to a parent's uid is SYSTEM_UID.
3623             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3624             // the |isolated| logic in the ProcessRecord constructor.
3625             info.uid = SYSTEM_UID;
3626             info.processName = processName;
3627             info.className = entryPoint;
3628             info.packageName = "android";
3629             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3630             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3631                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3632                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3633                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3634                     crashHandler);
3635             return proc != null ? proc.pid : 0;
3636         }
3637     }
3638
3639     final ProcessRecord startProcessLocked(String processName,
3640             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3641             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3642             boolean isolated, boolean keepIfLarge) {
3643         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3644                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3645                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3646                 null /* crashHandler */);
3647     }
3648
3649     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3650             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3651             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3652             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3653         long startTime = SystemClock.elapsedRealtime();
3654         ProcessRecord app;
3655         if (!isolated) {
3656             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3657             checkTime(startTime, "startProcess: after getProcessRecord");
3658
3659             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3660                 // If we are in the background, then check to see if this process
3661                 // is bad.  If so, we will just silently fail.
3662                 if (mAppErrors.isBadProcessLocked(info)) {
3663                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3664                             + "/" + info.processName);
3665                     return null;
3666                 }
3667             } else {
3668                 // When the user is explicitly starting a process, then clear its
3669                 // crash count so that we won't make it bad until they see at
3670                 // least one crash dialog again, and make the process good again
3671                 // if it had been bad.
3672                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3673                         + "/" + info.processName);
3674                 mAppErrors.resetProcessCrashTimeLocked(info);
3675                 if (mAppErrors.isBadProcessLocked(info)) {
3676                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3677                             UserHandle.getUserId(info.uid), info.uid,
3678                             info.processName);
3679                     mAppErrors.clearBadProcessLocked(info);
3680                     if (app != null) {
3681                         app.bad = false;
3682                     }
3683                 }
3684             }
3685         } else {
3686             // If this is an isolated process, it can't re-use an existing process.
3687             app = null;
3688         }
3689
3690         // We don't have to do anything more if:
3691         // (1) There is an existing application record; and
3692         // (2) The caller doesn't think it is dead, OR there is no thread
3693         //     object attached to it so we know it couldn't have crashed; and
3694         // (3) There is a pid assigned to it, so it is either starting or
3695         //     already running.
3696         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3697                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3698                 + " thread=" + (app != null ? app.thread : null)
3699                 + " pid=" + (app != null ? app.pid : -1));
3700         if (app != null && app.pid > 0) {
3701             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3702                 // We already have the app running, or are waiting for it to
3703                 // come up (we have a pid but not yet its thread), so keep it.
3704                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3705                 // If this is a new package in the process, add the package to the list
3706                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3707                 checkTime(startTime, "startProcess: done, added package to proc");
3708                 return app;
3709             }
3710
3711             // An application record is attached to a previous process,
3712             // clean it up now.
3713             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3714             checkTime(startTime, "startProcess: bad proc running, killing");
3715             killProcessGroup(app.uid, app.pid);
3716             handleAppDiedLocked(app, true, true);
3717             checkTime(startTime, "startProcess: done killing old proc");
3718         }
3719
3720         String hostingNameStr = hostingName != null
3721                 ? hostingName.flattenToShortString() : null;
3722
3723         if (app == null) {
3724             checkTime(startTime, "startProcess: creating new process record");
3725             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3726             if (app == null) {
3727                 Slog.w(TAG, "Failed making new process record for "
3728                         + processName + "/" + info.uid + " isolated=" + isolated);
3729                 return null;
3730             }
3731             app.crashHandler = crashHandler;
3732             checkTime(startTime, "startProcess: done creating new process record");
3733         } else {
3734             // If this is a new package in the process, add the package to the list
3735             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3736             checkTime(startTime, "startProcess: added package to existing proc");
3737         }
3738
3739         // If the system is not ready yet, then hold off on starting this
3740         // process until it is.
3741         if (!mProcessesReady
3742                 && !isAllowedWhileBooting(info)
3743                 && !allowWhileBooting) {
3744             if (!mProcessesOnHold.contains(app)) {
3745                 mProcessesOnHold.add(app);
3746             }
3747             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3748                     "System not ready, putting on hold: " + app);
3749             checkTime(startTime, "startProcess: returning with proc on hold");
3750             return app;
3751         }
3752
3753         checkTime(startTime, "startProcess: stepping in to startProcess");
3754         startProcessLocked(
3755                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3756         checkTime(startTime, "startProcess: done starting proc!");
3757         return (app.pid != 0) ? app : null;
3758     }
3759
3760     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3761         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3762     }
3763
3764     private final void startProcessLocked(ProcessRecord app,
3765             String hostingType, String hostingNameStr) {
3766         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3767                 null /* entryPoint */, null /* entryPointArgs */);
3768     }
3769
3770     private final void startProcessLocked(ProcessRecord app, String hostingType,
3771             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3772         long startTime = SystemClock.elapsedRealtime();
3773         if (app.pid > 0 && app.pid != MY_PID) {
3774             checkTime(startTime, "startProcess: removing from pids map");
3775             synchronized (mPidsSelfLocked) {
3776                 mPidsSelfLocked.remove(app.pid);
3777                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3778             }
3779             checkTime(startTime, "startProcess: done removing from pids map");
3780             app.setPid(0);
3781         }
3782
3783         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3784                 "startProcessLocked removing on hold: " + app);
3785         mProcessesOnHold.remove(app);
3786
3787         checkTime(startTime, "startProcess: starting to update cpu stats");
3788         updateCpuStats();
3789         checkTime(startTime, "startProcess: done updating cpu stats");
3790
3791         try {
3792             try {
3793                 final int userId = UserHandle.getUserId(app.uid);
3794                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3795             } catch (RemoteException e) {
3796                 throw e.rethrowAsRuntimeException();
3797             }
3798
3799             int uid = app.uid;
3800             int[] gids = null;
3801             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3802             if (!app.isolated) {
3803                 int[] permGids = null;
3804                 try {
3805                     checkTime(startTime, "startProcess: getting gids from package manager");
3806                     final IPackageManager pm = AppGlobals.getPackageManager();
3807                     permGids = pm.getPackageGids(app.info.packageName,
3808                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3809                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3810                             StorageManagerInternal.class);
3811                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3812                             app.info.packageName);
3813                 } catch (RemoteException e) {
3814                     throw e.rethrowAsRuntimeException();
3815                 }
3816
3817                 /*
3818                  * Add shared application and profile GIDs so applications can share some
3819                  * resources like shared libraries and access user-wide resources
3820                  */
3821                 if (ArrayUtils.isEmpty(permGids)) {
3822                     gids = new int[3];
3823                 } else {
3824                     gids = new int[permGids.length + 3];
3825                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3826                 }
3827                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3828                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3829                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3830
3831                 // Replace any invalid GIDs
3832                 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
3833                 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2];
3834             }
3835             checkTime(startTime, "startProcess: building args");
3836             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3837                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3838                         && mTopComponent != null
3839                         && app.processName.equals(mTopComponent.getPackageName())) {
3840                     uid = 0;
3841                 }
3842                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3843                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3844                     uid = 0;
3845                 }
3846             }
3847             int runtimeFlags = 0;
3848             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3849                 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP;
3850                 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3851                 // Also turn on CheckJNI for debuggable apps. It's quite
3852                 // awkward to turn on otherwise.
3853                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3854             }
3855             // Run the app in safe mode if its manifest requests so or the
3856             // system is booted in safe mode.
3857             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3858                 mSafeMode == true) {
3859                 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3860             }
3861             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3862                 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3863             }
3864             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3865             if ("true".equals(genDebugInfoProperty)) {
3866                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3867             }
3868             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3869                 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3870             }
3871             if ("1".equals(SystemProperties.get("debug.assert"))) {
3872                 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3873             }
3874             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3875                 // Enable all debug flags required by the native debugger.
3876                 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3877                 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3878                 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3879                 mNativeDebuggingApp = null;
3880             }
3881
3882             if (app.info.isPrivilegedApp() &&
3883                     !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
3884                 runtimeFlags |= Zygote.DISABLE_VERIFIER;
3885                 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES;
3886             }
3887
3888             if (app.info.isAllowedToUseHiddenApi()) {
3889                 // This app is allowed to use undocumented and private APIs. Set
3890                 // up its runtime with the appropriate flag.
3891                 runtimeFlags |= Zygote.DISABLE_HIDDEN_API_CHECKS;
3892             }
3893
3894             String invokeWith = null;
3895             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3896                 // Debuggable apps may include a wrapper script with their library directory.
3897                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3898                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3899                 try {
3900                     if (new File(wrapperFileName).exists()) {
3901                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3902                     }
3903                 } finally {
3904                     StrictMode.setThreadPolicy(oldPolicy);
3905                 }
3906             }
3907
3908             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3909             if (requiredAbi == null) {
3910                 requiredAbi = Build.SUPPORTED_ABIS[0];
3911             }
3912
3913             String instructionSet = null;
3914             if (app.info.primaryCpuAbi != null) {
3915                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3916             }
3917
3918             app.gids = gids;
3919             app.requiredAbi = requiredAbi;
3920             app.instructionSet = instructionSet;
3921
3922             // the per-user SELinux context must be set
3923             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3924                 Slog.wtf(TAG, "SELinux tag not defined",
3925                         new IllegalStateException("SELinux tag not defined for "
3926                         + app.info.packageName + " (uid " + app.uid + ")"));
3927             }
3928             final String seInfo = app.info.seInfo
3929                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3930             // Start the process.  It will either succeed and return a result containing
3931             // the PID of the new process, or else throw a RuntimeException.
3932             boolean isActivityProcess = (entryPoint == null);
3933             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3934             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3935                     app.processName);
3936             checkTime(startTime, "startProcess: asking zygote to start proc");
3937             ProcessStartResult startResult;
3938             if (hostingType.equals("webview_service")) {
3939                 startResult = startWebView(entryPoint,
3940                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3941                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3942                         app.info.dataDir, null, entryPointArgs);
3943             } else {
3944                 startResult = Process.start(entryPoint,
3945                         app.processName, uid, uid, gids, runtimeFlags, mountExternal,
3946                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3947                         app.info.dataDir, invokeWith, entryPointArgs);
3948             }
3949             checkTime(startTime, "startProcess: returned from zygote!");
3950             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3951
3952             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3953             checkTime(startTime, "startProcess: done updating battery stats");
3954
3955             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3956                     UserHandle.getUserId(uid), startResult.pid, uid,
3957                     app.processName, hostingType,
3958                     hostingNameStr != null ? hostingNameStr : "");
3959
3960             try {
3961                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3962                         seInfo, app.info.sourceDir, startResult.pid);
3963             } catch (RemoteException ex) {
3964                 // Ignore
3965             }
3966
3967             if (app.persistent) {
3968                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3969             }
3970
3971             checkTime(startTime, "startProcess: building log message");
3972             StringBuilder buf = mStringBuilder;
3973             buf.setLength(0);
3974             buf.append("Start proc ");
3975             buf.append(startResult.pid);
3976             buf.append(':');
3977             buf.append(app.processName);
3978             buf.append('/');
3979             UserHandle.formatUid(buf, uid);
3980             if (!isActivityProcess) {
3981                 buf.append(" [");
3982                 buf.append(entryPoint);
3983                 buf.append("]");
3984             }
3985             buf.append(" for ");
3986             buf.append(hostingType);
3987             if (hostingNameStr != null) {
3988                 buf.append(" ");
3989                 buf.append(hostingNameStr);
3990             }
3991             Slog.i(TAG, buf.toString());
3992             app.setPid(startResult.pid);
3993             app.usingWrapper = startResult.usingWrapper;
3994             app.removed = false;
3995             app.killed = false;
3996             app.killedByAm = false;
3997             checkTime(startTime, "startProcess: starting to update pids map");
3998             ProcessRecord oldApp;
3999             synchronized (mPidsSelfLocked) {
4000                 oldApp = mPidsSelfLocked.get(startResult.pid);
4001             }
4002             // If there is already an app occupying that pid that hasn't been cleaned up
4003             if (oldApp != null && !app.isolated) {
4004                 // Clean up anything relating to this pid first
4005                 Slog.w(TAG, "Reusing pid " + startResult.pid
4006                         + " while app is still mapped to it");
4007                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4008                         true /*replacingPid*/);
4009             }
4010             synchronized (mPidsSelfLocked) {
4011                 this.mPidsSelfLocked.put(startResult.pid, app);
4012                 if (isActivityProcess) {
4013                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4014                     msg.obj = app;
4015                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4016                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4017                 }
4018             }
4019             checkTime(startTime, "startProcess: done updating pids map");
4020         } catch (RuntimeException e) {
4021             Slog.e(TAG, "Failure starting process " + app.processName, e);
4022
4023             // Something went very wrong while trying to start this process; one
4024             // common case is when the package is frozen due to an active
4025             // upgrade. To recover, clean up any active bookkeeping related to
4026             // starting this process. (We already invoked this method once when
4027             // the package was initially frozen through KILL_APPLICATION_MSG, so
4028             // it doesn't hurt to use it again.)
4029             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4030                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4031         }
4032     }
4033
4034     void updateUsageStats(ActivityRecord component, boolean resumed) {
4035         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4036                 "updateUsageStats: comp=" + component + "res=" + resumed);
4037         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4038         if (resumed) {
4039             if (mUsageStatsService != null) {
4040                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4042             }
4043             synchronized (stats) {
4044                 stats.noteActivityResumedLocked(component.app.uid);
4045             }
4046         } else {
4047             if (mUsageStatsService != null) {
4048                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4049                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4050             }
4051             synchronized (stats) {
4052                 stats.noteActivityPausedLocked(component.app.uid);
4053             }
4054         }
4055     }
4056
4057     Intent getHomeIntent() {
4058         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4059         intent.setComponent(mTopComponent);
4060         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4061         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4062             intent.addCategory(Intent.CATEGORY_HOME);
4063         }
4064         return intent;
4065     }
4066
4067     boolean startHomeActivityLocked(int userId, String reason) {
4068         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4069                 && mTopAction == null) {
4070             // We are running in factory test mode, but unable to find
4071             // the factory test app, so just sit around displaying the
4072             // error message and don't try to start anything.
4073             return false;
4074         }
4075         Intent intent = getHomeIntent();
4076         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4077         if (aInfo != null) {
4078             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4079             // Don't do this if the home app is currently being
4080             // instrumented.
4081             aInfo = new ActivityInfo(aInfo);
4082             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4083             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4084                     aInfo.applicationInfo.uid, true);
4085             if (app == null || app.instr == null) {
4086                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4087                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4088                 // For ANR debugging to verify if the user activity is the one that actually
4089                 // launched.
4090                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4091                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4092             }
4093         } else {
4094             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4095         }
4096
4097         return true;
4098     }
4099
4100     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4101         ActivityInfo ai = null;
4102         ComponentName comp = intent.getComponent();
4103         try {
4104             if (comp != null) {
4105                 // Factory test.
4106                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4107             } else {
4108                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4109                         intent,
4110                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4111                         flags, userId);
4112
4113                 if (info != null) {
4114                     ai = info.activityInfo;
4115                 }
4116             }
4117         } catch (RemoteException e) {
4118             // ignore
4119         }
4120
4121         return ai;
4122     }
4123
4124     /**
4125      * Starts the "new version setup screen" if appropriate.
4126      */
4127     void startSetupActivityLocked() {
4128         // Only do this once per boot.
4129         if (mCheckedForSetup) {
4130             return;
4131         }
4132
4133         // We will show this screen if the current one is a different
4134         // version than the last one shown, and we are not running in
4135         // low-level factory test mode.
4136         final ContentResolver resolver = mContext.getContentResolver();
4137         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4138                 Settings.Global.getInt(resolver,
4139                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4140             mCheckedForSetup = true;
4141
4142             // See if we should be showing the platform update setup UI.
4143             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4144             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4145                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4146             if (!ris.isEmpty()) {
4147                 final ResolveInfo ri = ris.get(0);
4148                 String vers = ri.activityInfo.metaData != null
4149                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4150                         : null;
4151                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4152                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4153                             Intent.METADATA_SETUP_VERSION);
4154                 }
4155                 String lastVers = Settings.Secure.getString(
4156                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4157                 if (vers != null && !vers.equals(lastVers)) {
4158                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4159                     intent.setComponent(new ComponentName(
4160                             ri.activityInfo.packageName, ri.activityInfo.name));
4161                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4162                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4163                             null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4164                 }
4165             }
4166         }
4167     }
4168
4169     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4170         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4171     }
4172
4173     void enforceNotIsolatedCaller(String caller) {
4174         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4175             throw new SecurityException("Isolated process not allowed to call " + caller);
4176         }
4177     }
4178
4179     void enforceShellRestriction(String restriction, int userHandle) {
4180         if (Binder.getCallingUid() == SHELL_UID) {
4181             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4182                 throw new SecurityException("Shell does not have permission to access user "
4183                         + userHandle);
4184             }
4185         }
4186     }
4187
4188     @Override
4189     public int getFrontActivityScreenCompatMode() {
4190         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4191         synchronized (this) {
4192             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4193         }
4194     }
4195
4196     @Override
4197     public void setFrontActivityScreenCompatMode(int mode) {
4198         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4199                 "setFrontActivityScreenCompatMode");
4200         synchronized (this) {
4201             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4202         }
4203     }
4204
4205     @Override
4206     public int getPackageScreenCompatMode(String packageName) {
4207         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4208         synchronized (this) {
4209             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4210         }
4211     }
4212
4213     @Override
4214     public void setPackageScreenCompatMode(String packageName, int mode) {
4215         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4216                 "setPackageScreenCompatMode");
4217         synchronized (this) {
4218             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4219         }
4220     }
4221
4222     @Override
4223     public boolean getPackageAskScreenCompat(String packageName) {
4224         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4225         synchronized (this) {
4226             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4227         }
4228     }
4229
4230     @Override
4231     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4232         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4233                 "setPackageAskScreenCompat");
4234         synchronized (this) {
4235             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4236         }
4237     }
4238
4239     private boolean hasUsageStatsPermission(String callingPackage) {
4240         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4241                 Binder.getCallingUid(), callingPackage);
4242         if (mode == AppOpsManager.MODE_DEFAULT) {
4243             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4244                     == PackageManager.PERMISSION_GRANTED;
4245         }
4246         return mode == AppOpsManager.MODE_ALLOWED;
4247     }
4248
4249     @Override
4250     public int getPackageProcessState(String packageName, String callingPackage) {
4251         if (!hasUsageStatsPermission(callingPackage)) {
4252             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4253                     "getPackageProcessState");
4254         }
4255
4256         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4257         synchronized (this) {
4258             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4259                 final ProcessRecord proc = mLruProcesses.get(i);
4260                 if (procState > proc.setProcState) {
4261                     if (proc.pkgList.containsKey(packageName) ||
4262                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4263                         procState = proc.setProcState;
4264                     }
4265                 }
4266             }
4267         }
4268         return procState;
4269     }
4270
4271     @Override
4272     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4273             throws RemoteException {
4274         synchronized (this) {
4275             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4276             if (app == null) {
4277                 throw new IllegalArgumentException("Unknown process: " + process);
4278             }
4279             if (app.thread == null) {
4280                 throw new IllegalArgumentException("Process has no app thread");
4281             }
4282             if (app.trimMemoryLevel >= level) {
4283                 throw new IllegalArgumentException(
4284                         "Unable to set a higher trim level than current level");
4285             }
4286             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4287                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4288                 throw new IllegalArgumentException("Unable to set a background trim level "
4289                     + "on a foreground process");
4290             }
4291             app.thread.scheduleTrimMemory(level);
4292             app.trimMemoryLevel = level;
4293             return true;
4294         }
4295     }
4296
4297     private void dispatchProcessesChanged() {
4298         int N;
4299         synchronized (this) {
4300             N = mPendingProcessChanges.size();
4301             if (mActiveProcessChanges.length < N) {
4302                 mActiveProcessChanges = new ProcessChangeItem[N];
4303             }
4304             mPendingProcessChanges.toArray(mActiveProcessChanges);
4305             mPendingProcessChanges.clear();
4306             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4307                     "*** Delivering " + N + " process changes");
4308         }
4309
4310         int i = mProcessObservers.beginBroadcast();
4311         while (i > 0) {
4312             i--;
4313             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4314             if (observer != null) {
4315                 try {
4316                     for (int j=0; j<N; j++) {
4317                         ProcessChangeItem item = mActiveProcessChanges[j];
4318                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4319                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4320                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4321                                     + item.uid + ": " + item.foregroundActivities);
4322                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4323                                     item.foregroundActivities);
4324                         }
4325                     }
4326                 } catch (RemoteException e) {
4327                 }
4328             }
4329         }
4330         mProcessObservers.finishBroadcast();
4331
4332         synchronized (this) {
4333             for (int j=0; j<N; j++) {
4334                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4335             }
4336         }
4337     }
4338
4339     private void dispatchProcessDied(int pid, int uid) {
4340         int i = mProcessObservers.beginBroadcast();
4341         while (i > 0) {
4342             i--;
4343             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4344             if (observer != null) {
4345                 try {
4346                     observer.onProcessDied(pid, uid);
4347                 } catch (RemoteException e) {
4348                 }
4349             }
4350         }
4351         mProcessObservers.finishBroadcast();
4352     }
4353
4354     @VisibleForTesting
4355     void dispatchUidsChanged() {
4356         int N;
4357         synchronized (this) {
4358             N = mPendingUidChanges.size();
4359             if (mActiveUidChanges.length < N) {
4360                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4361             }
4362             for (int i=0; i<N; i++) {
4363                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4364                 mActiveUidChanges[i] = change;
4365                 if (change.uidRecord != null) {
4366                     change.uidRecord.pendingChange = null;
4367                     change.uidRecord = null;
4368                 }
4369             }
4370             mPendingUidChanges.clear();
4371             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4372                     "*** Delivering " + N + " uid changes");
4373         }
4374
4375         int i = mUidObservers.beginBroadcast();
4376         while (i > 0) {
4377             i--;
4378             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4379                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4380         }
4381         mUidObservers.finishBroadcast();
4382
4383         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4384             for (int j = 0; j < N; ++j) {
4385                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4386                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4387                     mValidateUids.remove(item.uid);
4388                 } else {
4389                     UidRecord validateUid = mValidateUids.get(item.uid);
4390                     if (validateUid == null) {
4391                         validateUid = new UidRecord(item.uid);
4392                         mValidateUids.put(item.uid, validateUid);
4393                     }
4394                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4395                         validateUid.idle = true;
4396                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4397                         validateUid.idle = false;
4398                     }
4399                     validateUid.curProcState = validateUid.setProcState = item.processState;
4400                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4401                 }
4402             }
4403         }
4404
4405         synchronized (this) {
4406             for (int j = 0; j < N; j++) {
4407                 mAvailUidChanges.add(mActiveUidChanges[j]);
4408             }
4409         }
4410     }
4411
4412     private void dispatchUidsChangedForObserver(IUidObserver observer,
4413             UidObserverRegistration reg, int changesSize) {
4414         if (observer == null) {
4415             return;
4416         }
4417         try {
4418             for (int j = 0; j < changesSize; j++) {
4419                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4420                 final int change = item.change;
4421                 if (change == UidRecord.CHANGE_PROCSTATE &&
4422                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4423                     // No-op common case: no significant change, the observer is not
4424                     // interested in all proc state changes.
4425                     continue;
4426                 }
4427                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4428                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4429                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4430                                 "UID idle uid=" + item.uid);
4431                         observer.onUidIdle(item.uid, item.ephemeral);
4432                     }
4433                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4434                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4435                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4436                                 "UID active uid=" + item.uid);
4437                         observer.onUidActive(item.uid);
4438                     }
4439                 }
4440                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4441                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
4442                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4443                                 "UID cached uid=" + item.uid);
4444                         observer.onUidCachedChanged(item.uid, true);
4445                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4446                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4447                                 "UID active uid=" + item.uid);
4448                         observer.onUidCachedChanged(item.uid, false);
4449                     }
4450                 }
4451                 if ((change & UidRecord.CHANGE_GONE) != 0) {
4452                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4453                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454                                 "UID gone uid=" + item.uid);
4455                         observer.onUidGone(item.uid, item.ephemeral);
4456                     }
4457                     if (reg.lastProcStates != null) {
4458                         reg.lastProcStates.delete(item.uid);
4459                     }
4460                 } else {
4461                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4462                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4463                                 "UID CHANGED uid=" + item.uid
4464                                         + ": " + item.processState);
4465                         boolean doReport = true;
4466                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4467                             final int lastState = reg.lastProcStates.get(item.uid,
4468                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4469                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4470                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4471                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4472                                 doReport = lastAboveCut != newAboveCut;
4473                             } else {
4474                                 doReport = item.processState
4475                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4476                             }
4477                         }
4478                         if (doReport) {
4479                             if (reg.lastProcStates != null) {
4480                                 reg.lastProcStates.put(item.uid, item.processState);
4481                             }
4482                             observer.onUidStateChanged(item.uid, item.processState,
4483                                     item.procStateSeq);
4484                         }
4485                     }
4486                 }
4487             }
4488         } catch (RemoteException e) {
4489         }
4490     }
4491
4492     void dispatchOomAdjObserver(String msg) {
4493         OomAdjObserver observer;
4494         synchronized (this) {
4495             observer = mCurOomAdjObserver;
4496         }
4497
4498         if (observer != null) {
4499             observer.onOomAdjMessage(msg);
4500         }
4501     }
4502
4503     void setOomAdjObserver(int uid, OomAdjObserver observer) {
4504         synchronized (this) {
4505             mCurOomAdjUid = uid;
4506             mCurOomAdjObserver = observer;
4507         }
4508     }
4509
4510     void clearOomAdjObserver() {
4511         synchronized (this) {
4512             mCurOomAdjUid = -1;
4513             mCurOomAdjObserver = null;
4514         }
4515     }
4516
4517     void reportOomAdjMessageLocked(String tag, String msg) {
4518         Slog.d(tag, msg);
4519         if (mCurOomAdjObserver != null) {
4520             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4521         }
4522     }
4523
4524     @Override
4525     public final int startActivity(IApplicationThread caller, String callingPackage,
4526             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4528         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4529                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4530                 UserHandle.getCallingUserId());
4531     }
4532
4533     @Override
4534     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4535             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4536             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4537         enforceNotIsolatedCaller("startActivity");
4538         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4539                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4540         // TODO: Switch to user app stacks here.
4541         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4542                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4543                 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4544     }
4545
4546     @Override
4547     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4548             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4549             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4550             int userId) {
4551
4552         // This is very dangerous -- it allows you to perform a start activity (including
4553         // permission grants) as any app that may launch one of your own activities.  So
4554         // we will only allow this to be done from activities that are part of the core framework,
4555         // and then only when they are running as the system.
4556         final ActivityRecord sourceRecord;
4557         final int targetUid;
4558         final String targetPackage;
4559         synchronized (this) {
4560             if (resultTo == null) {
4561                 throw new SecurityException("Must be called from an activity");
4562             }
4563             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4564             if (sourceRecord == null) {
4565                 throw new SecurityException("Called with bad activity token: " + resultTo);
4566             }
4567             if (!sourceRecord.info.packageName.equals("android")) {
4568                 throw new SecurityException(
4569                         "Must be called from an activity that is declared in the android package");
4570             }
4571             if (sourceRecord.app == null) {
4572                 throw new SecurityException("Called without a process attached to activity");
4573             }
4574             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4575                 // This is still okay, as long as this activity is running under the
4576                 // uid of the original calling activity.
4577                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4578                     throw new SecurityException(
4579                             "Calling activity in uid " + sourceRecord.app.uid
4580                                     + " must be system uid or original calling uid "
4581                                     + sourceRecord.launchedFromUid);
4582                 }
4583             }
4584             if (ignoreTargetSecurity) {
4585                 if (intent.getComponent() == null) {
4586                     throw new SecurityException(
4587                             "Component must be specified with ignoreTargetSecurity");
4588                 }
4589                 if (intent.getSelector() != null) {
4590                     throw new SecurityException(
4591                             "Selector not allowed with ignoreTargetSecurity");
4592                 }
4593             }
4594             targetUid = sourceRecord.launchedFromUid;
4595             targetPackage = sourceRecord.launchedFromPackage;
4596         }
4597
4598         if (userId == UserHandle.USER_NULL) {
4599             userId = UserHandle.getUserId(sourceRecord.app.uid);
4600         }
4601
4602         // TODO: Switch to user app stacks here.
4603         try {
4604             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4605                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4606                     null, null, bOptions, ignoreTargetSecurity, userId, null,
4607                     "startActivityAsCaller");
4608             return ret;
4609         } catch (SecurityException e) {
4610             // XXX need to figure out how to propagate to original app.
4611             // A SecurityException here is generally actually a fault of the original
4612             // calling activity (such as a fairly granting permissions), so propagate it
4613             // back to them.
4614             /*
4615             StringBuilder msg = new StringBuilder();
4616             msg.append("While launching");
4617             msg.append(intent.toString());
4618             msg.append(": ");
4619             msg.append(e.getMessage());
4620             */
4621             throw e;
4622         }
4623     }
4624
4625     @Override
4626     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4627             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4628             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4629         enforceNotIsolatedCaller("startActivityAndWait");
4630         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4631                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4632         WaitResult res = new WaitResult();
4633         // TODO: Switch to user app stacks here.
4634         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4635                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4636                 bOptions, false, userId, null, "startActivityAndWait");
4637         return res;
4638     }
4639
4640     @Override
4641     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4642             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4643             int startFlags, Configuration config, Bundle bOptions, int userId) {
4644         enforceNotIsolatedCaller("startActivityWithConfig");
4645         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4646                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4647         // TODO: Switch to user app stacks here.
4648         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4649                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4650                 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4651         return ret;
4652     }
4653
4654     @Override
4655     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4656             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4657             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4658             throws TransactionTooLargeException {
4659         enforceNotIsolatedCaller("startActivityIntentSender");
4660         // Refuse possible leaked file descriptors
4661         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4662             throw new IllegalArgumentException("File descriptors passed in Intent");
4663         }
4664
4665         if (!(target instanceof PendingIntentRecord)) {
4666             throw new IllegalArgumentException("Bad PendingIntent object");
4667         }
4668
4669         PendingIntentRecord pir = (PendingIntentRecord)target;
4670
4671         synchronized (this) {
4672             // If this is coming from the currently resumed activity, it is
4673             // effectively saying that app switches are allowed at this point.
4674             final ActivityStack stack = getFocusedStack();
4675             if (stack.mResumedActivity != null &&
4676                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4677                 mAppSwitchesAllowedTime = 0;
4678             }
4679         }
4680         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4681                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4682         return ret;
4683     }
4684
4685     @Override
4686     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4687             Intent intent, String resolvedType, IVoiceInteractionSession session,
4688             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4689             Bundle bOptions, int userId) {
4690         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4691                 != PackageManager.PERMISSION_GRANTED) {
4692             String msg = "Permission Denial: startVoiceActivity() from pid="
4693                     + Binder.getCallingPid()
4694                     + ", uid=" + Binder.getCallingUid()
4695                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4696             Slog.w(TAG, msg);
4697             throw new SecurityException(msg);
4698         }
4699         if (session == null || interactor == null) {
4700             throw new NullPointerException("null session or interactor");
4701         }
4702         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4703                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4704         // TODO: Switch to user app stacks here.
4705         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4706                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4707                 null, bOptions, false, userId, null, "startVoiceActivity");
4708     }
4709
4710     @Override
4711     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4712             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4713         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4714                 != PackageManager.PERMISSION_GRANTED) {
4715             final String msg = "Permission Denial: startAssistantActivity() from pid="
4716                     + Binder.getCallingPid()
4717                     + ", uid=" + Binder.getCallingUid()
4718                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4719             Slog.w(TAG, msg);
4720             throw new SecurityException(msg);
4721         }
4722         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4723                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4724         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4725                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4726                 userId, null, "startAssistantActivity");
4727     }
4728
4729     @Override
4730     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4731             throws RemoteException {
4732         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4733         synchronized (this) {
4734             ActivityRecord activity = getFocusedStack().topActivity();
4735             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4736                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4737             }
4738             if (mRunningVoice != null || activity.getTask().voiceSession != null
4739                     || activity.voiceSession != null) {
4740                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4741                 return;
4742             }
4743             if (activity.pendingVoiceInteractionStart) {
4744                 Slog.w(TAG, "Pending start of voice interaction already.");
4745                 return;
4746             }
4747             activity.pendingVoiceInteractionStart = true;
4748         }
4749         LocalServices.getService(VoiceInteractionManagerInternal.class)
4750                 .startLocalVoiceInteraction(callingActivity, options);
4751     }
4752
4753     @Override
4754     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4755         LocalServices.getService(VoiceInteractionManagerInternal.class)
4756                 .stopLocalVoiceInteraction(callingActivity);
4757     }
4758
4759     @Override
4760     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4761         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4762                 .supportsLocalVoiceInteraction();
4763     }
4764
4765     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4766             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4767         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4768         if (activityToCallback == null) return;
4769         activityToCallback.setVoiceSessionLocked(voiceSession);
4770
4771         // Inform the activity
4772         try {
4773             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4774                     voiceInteractor);
4775             long token = Binder.clearCallingIdentity();
4776             try {
4777                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4778             } finally {
4779                 Binder.restoreCallingIdentity(token);
4780             }
4781             // TODO: VI Should we cache the activity so that it's easier to find later
4782             // rather than scan through all the stacks and activities?
4783         } catch (RemoteException re) {
4784             activityToCallback.clearVoiceSessionLocked();
4785             // TODO: VI Should this terminate the voice session?
4786         }
4787     }
4788
4789     @Override
4790     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4791         synchronized (this) {
4792             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4793                 if (keepAwake) {
4794                     mVoiceWakeLock.acquire();
4795                 } else {
4796                     mVoiceWakeLock.release();
4797                 }
4798             }
4799         }
4800     }
4801
4802     @Override
4803     public boolean startNextMatchingActivity(IBinder callingActivity,
4804             Intent intent, Bundle bOptions) {
4805         // Refuse possible leaked file descriptors
4806         if (intent != null && intent.hasFileDescriptors() == true) {
4807             throw new IllegalArgumentException("File descriptors passed in Intent");
4808         }
4809         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4810
4811         synchronized (this) {
4812             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4813             if (r == null) {
4814                 ActivityOptions.abort(options);
4815                 return false;
4816             }
4817             if (r.app == null || r.app.thread == null) {
4818                 // The caller is not running...  d'oh!
4819                 ActivityOptions.abort(options);
4820                 return false;
4821             }
4822             intent = new Intent(intent);
4823             // The caller is not allowed to change the data.
4824             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4825             // And we are resetting to find the next component...
4826             intent.setComponent(null);
4827
4828             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4829
4830             ActivityInfo aInfo = null;
4831             try {
4832                 List<ResolveInfo> resolves =
4833                     AppGlobals.getPackageManager().queryIntentActivities(
4834                             intent, r.resolvedType,
4835                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4836                             UserHandle.getCallingUserId()).getList();
4837
4838                 // Look for the original activity in the list...
4839                 final int N = resolves != null ? resolves.size() : 0;
4840                 for (int i=0; i<N; i++) {
4841                     ResolveInfo rInfo = resolves.get(i);
4842                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4843                             && rInfo.activityInfo.name.equals(r.info.name)) {
4844                         // We found the current one...  the next matching is
4845                         // after it.
4846                         i++;
4847                         if (i<N) {
4848                             aInfo = resolves.get(i).activityInfo;
4849                         }
4850                         if (debug) {
4851                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4852                                     + "/" + r.info.name);
4853                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4854                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4855                         }
4856                         break;
4857                     }
4858                 }
4859             } catch (RemoteException e) {
4860             }
4861
4862             if (aInfo == null) {
4863                 // Nobody who is next!
4864                 ActivityOptions.abort(options);
4865                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4866                 return false;
4867             }
4868
4869             intent.setComponent(new ComponentName(
4870                     aInfo.applicationInfo.packageName, aInfo.name));
4871             intent.setFlags(intent.getFlags()&~(
4872                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4873                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4874                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4875                     Intent.FLAG_ACTIVITY_NEW_TASK));
4876
4877             // Okay now we need to start the new activity, replacing the
4878             // currently running activity.  This is a little tricky because
4879             // we want to start the new one as if the current one is finished,
4880             // but not finish the current one first so that there is no flicker.
4881             // And thus...
4882             final boolean wasFinishing = r.finishing;
4883             r.finishing = true;
4884
4885             // Propagate reply information over to the new activity.
4886             final ActivityRecord resultTo = r.resultTo;
4887             final String resultWho = r.resultWho;
4888             final int requestCode = r.requestCode;
4889             r.resultTo = null;
4890             if (resultTo != null) {
4891                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4892             }
4893
4894             final long origId = Binder.clearCallingIdentity();
4895             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4896                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4897                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4898                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4899                     false, false, null, null, "startNextMatchingActivity");
4900             Binder.restoreCallingIdentity(origId);
4901
4902             r.finishing = wasFinishing;
4903             if (res != ActivityManager.START_SUCCESS) {
4904                 return false;
4905             }
4906             return true;
4907         }
4908     }
4909
4910     @Override
4911     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4912         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4913             String msg = "Permission Denial: startActivityFromRecents called without " +
4914                     START_TASKS_FROM_RECENTS;
4915             Slog.w(TAG, msg);
4916             throw new SecurityException(msg);
4917         }
4918         final long origId = Binder.clearCallingIdentity();
4919         try {
4920             synchronized (this) {
4921                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4922             }
4923         } finally {
4924             Binder.restoreCallingIdentity(origId);
4925         }
4926     }
4927
4928     final int startActivityInPackage(int uid, String callingPackage,
4929             Intent intent, String resolvedType, IBinder resultTo,
4930             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4931             TaskRecord inTask, String reason) {
4932
4933         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4934                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4935
4936         // TODO: Switch to user app stacks here.
4937         return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4938                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4939                 null, null, null, bOptions, false, userId, inTask, reason);
4940     }
4941
4942     @Override
4943     public final int startActivities(IApplicationThread caller, String callingPackage,
4944             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4945             int userId) {
4946         final String reason = "startActivities";
4947         enforceNotIsolatedCaller(reason);
4948         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4949                 userId, false, ALLOW_FULL_ONLY, reason, null);
4950         // TODO: Switch to user app stacks here.
4951         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4952                 resolvedTypes, resultTo, bOptions, userId, reason);
4953         return ret;
4954     }
4955
4956     final int startActivitiesInPackage(int uid, String callingPackage,
4957             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4958             Bundle bOptions, int userId) {
4959
4960         final String reason = "startActivityInPackage";
4961         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4962                 userId, false, ALLOW_FULL_ONLY, reason, null);
4963         // TODO: Switch to user app stacks here.
4964         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4965                 resultTo, bOptions, userId, reason);
4966         return ret;
4967     }
4968
4969     @Override
4970     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4971         synchronized (this) {
4972             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4973             if (r == null) {
4974                 return;
4975             }
4976             r.reportFullyDrawnLocked(restoredFromBundle);
4977         }
4978     }
4979
4980     @Override
4981     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4982         synchronized (this) {
4983             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984             if (r == null) {
4985                 return;
4986             }
4987             final long origId = Binder.clearCallingIdentity();
4988             try {
4989                 r.setRequestedOrientation(requestedOrientation);
4990             } finally {
4991                 Binder.restoreCallingIdentity(origId);
4992             }
4993         }
4994     }
4995
4996     @Override
4997     public int getRequestedOrientation(IBinder token) {
4998         synchronized (this) {
4999             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5000             if (r == null) {
5001                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5002             }
5003             return r.getRequestedOrientation();
5004         }
5005     }
5006
5007     @Override
5008     public final void requestActivityRelaunch(IBinder token) {
5009         synchronized(this) {
5010             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5011             if (r == null) {
5012                 return;
5013             }
5014             final long origId = Binder.clearCallingIdentity();
5015             try {
5016                 r.forceNewConfig = true;
5017                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5018                         true /* preserveWindow */);
5019             } finally {
5020                 Binder.restoreCallingIdentity(origId);
5021             }
5022         }
5023     }
5024
5025     /**
5026      * This is the internal entry point for handling Activity.finish().
5027      *
5028      * @param token The Binder token referencing the Activity we want to finish.
5029      * @param resultCode Result code, if any, from this Activity.
5030      * @param resultData Result data (Intent), if any, from this Activity.
5031      * @param finishTask Whether to finish the task associated with this Activity.
5032      *
5033      * @return Returns true if the activity successfully finished, or false if it is still running.
5034      */
5035     @Override
5036     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5037             int finishTask) {
5038         // Refuse possible leaked file descriptors
5039         if (resultData != null && resultData.hasFileDescriptors() == true) {
5040             throw new IllegalArgumentException("File descriptors passed in Intent");
5041         }
5042
5043         synchronized(this) {
5044             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5045             if (r == null) {
5046                 return true;
5047             }
5048             // Keep track of the root activity of the task before we finish it
5049             TaskRecord tr = r.getTask();
5050             ActivityRecord rootR = tr.getRootActivity();
5051             if (rootR == null) {
5052                 Slog.w(TAG, "Finishing task with all activities already finished");
5053             }
5054             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5055             // finish.
5056             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5057                     mStackSupervisor.isLastLockedTask(tr)) {
5058                 Slog.i(TAG, "Not finishing task in lock task mode");
5059                 mStackSupervisor.showLockTaskToast();
5060                 return false;
5061             }
5062             if (mController != null) {
5063                 // Find the first activity that is not finishing.
5064                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5065                 if (next != null) {
5066                     // ask watcher if this is allowed
5067                     boolean resumeOK = true;
5068                     try {
5069                         resumeOK = mController.activityResuming(next.packageName);
5070                     } catch (RemoteException e) {
5071                         mController = null;
5072                         Watchdog.getInstance().setActivityController(null);
5073                     }
5074
5075                     if (!resumeOK) {
5076                         Slog.i(TAG, "Not finishing activity because controller resumed");
5077                         return false;
5078                     }
5079                 }
5080             }
5081             final long origId = Binder.clearCallingIdentity();
5082             try {
5083                 boolean res;
5084                 final boolean finishWithRootActivity =
5085                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5086                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5087                         || (finishWithRootActivity && r == rootR)) {
5088                     // If requested, remove the task that is associated to this activity only if it
5089                     // was the root activity in the task. The result code and data is ignored
5090                     // because we don't support returning them across task boundaries. Also, to
5091                     // keep backwards compatibility we remove the task from recents when finishing
5092                     // task with root activity.
5093                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5094                     if (!res) {
5095                         Slog.i(TAG, "Removing task failed to finish activity");
5096                     }
5097                 } else {
5098                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5099                             resultData, "app-request", true);
5100                     if (!res) {
5101                         Slog.i(TAG, "Failed to finish by app-request");
5102                     }
5103                 }
5104                 return res;
5105             } finally {
5106                 Binder.restoreCallingIdentity(origId);
5107             }
5108         }
5109     }
5110
5111     @Override
5112     public final void finishHeavyWeightApp() {
5113         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5114                 != PackageManager.PERMISSION_GRANTED) {
5115             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5116                     + Binder.getCallingPid()
5117                     + ", uid=" + Binder.getCallingUid()
5118                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5119             Slog.w(TAG, msg);
5120             throw new SecurityException(msg);
5121         }
5122
5123         synchronized(this) {
5124             if (mHeavyWeightProcess == null) {
5125                 return;
5126             }
5127
5128             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5129             for (int i = 0; i < activities.size(); i++) {
5130                 ActivityRecord r = activities.get(i);
5131                 if (!r.finishing && r.isInStackLocked()) {
5132                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5133                             null, "finish-heavy", true);
5134                 }
5135             }
5136
5137             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5138                     mHeavyWeightProcess.userId, 0));
5139             mHeavyWeightProcess = null;
5140         }
5141     }
5142
5143     @Override
5144     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5145             String message) {
5146         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5147                 != PackageManager.PERMISSION_GRANTED) {
5148             String msg = "Permission Denial: crashApplication() from pid="
5149                     + Binder.getCallingPid()
5150                     + ", uid=" + Binder.getCallingUid()
5151                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5152             Slog.w(TAG, msg);
5153             throw new SecurityException(msg);
5154         }
5155
5156         synchronized(this) {
5157             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5158         }
5159     }
5160
5161     @Override
5162     public final void finishSubActivity(IBinder token, String resultWho,
5163             int requestCode) {
5164         synchronized(this) {
5165             final long origId = Binder.clearCallingIdentity();
5166             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5167             if (r != null) {
5168                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5169             }
5170             Binder.restoreCallingIdentity(origId);
5171         }
5172     }
5173
5174     @Override
5175     public boolean finishActivityAffinity(IBinder token) {
5176         synchronized(this) {
5177             final long origId = Binder.clearCallingIdentity();
5178             try {
5179                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5180                 if (r == null) {
5181                     return false;
5182                 }
5183
5184                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5185                 // can finish.
5186                 final TaskRecord task = r.getTask();
5187                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5188                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5189                     mStackSupervisor.showLockTaskToast();
5190                     return false;
5191                 }
5192                 return task.getStack().finishActivityAffinityLocked(r);
5193             } finally {
5194                 Binder.restoreCallingIdentity(origId);
5195             }
5196         }
5197     }
5198
5199     @Override
5200     public void finishVoiceTask(IVoiceInteractionSession session) {
5201         synchronized (this) {
5202             final long origId = Binder.clearCallingIdentity();
5203             try {
5204                 // TODO: VI Consider treating local voice interactions and voice tasks
5205                 // differently here
5206                 mStackSupervisor.finishVoiceTask(session);
5207             } finally {
5208                 Binder.restoreCallingIdentity(origId);
5209             }
5210         }
5211
5212     }
5213
5214     @Override
5215     public boolean releaseActivityInstance(IBinder token) {
5216         synchronized(this) {
5217             final long origId = Binder.clearCallingIdentity();
5218             try {
5219                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5220                 if (r == null) {
5221                     return false;
5222                 }
5223                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5224             } finally {
5225                 Binder.restoreCallingIdentity(origId);
5226             }
5227         }
5228     }
5229
5230     @Override
5231     public void releaseSomeActivities(IApplicationThread appInt) {
5232         synchronized(this) {
5233             final long origId = Binder.clearCallingIdentity();
5234             try {
5235                 ProcessRecord app = getRecordForAppLocked(appInt);
5236                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5237             } finally {
5238                 Binder.restoreCallingIdentity(origId);
5239             }
5240         }
5241     }
5242
5243     @Override
5244     public boolean willActivityBeVisible(IBinder token) {
5245         synchronized(this) {
5246             ActivityStack stack = ActivityRecord.getStackLocked(token);
5247             if (stack != null) {
5248                 return stack.willActivityBeVisibleLocked(token);
5249             }
5250             return false;
5251         }
5252     }
5253
5254     @Override
5255     public void overridePendingTransition(IBinder token, String packageName,
5256             int enterAnim, int exitAnim) {
5257         synchronized(this) {
5258             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5259             if (self == null) {
5260                 return;
5261             }
5262
5263             final long origId = Binder.clearCallingIdentity();
5264
5265             if (self.state == ActivityState.RESUMED
5266                     || self.state == ActivityState.PAUSING) {
5267                 mWindowManager.overridePendingAppTransition(packageName,
5268                         enterAnim, exitAnim, null);
5269             }
5270
5271             Binder.restoreCallingIdentity(origId);
5272         }
5273     }
5274
5275     /**
5276      * Main function for removing an existing process from the activity manager
5277      * as a result of that process going away.  Clears out all connections
5278      * to the process.
5279      */
5280     private final void handleAppDiedLocked(ProcessRecord app,
5281             boolean restarting, boolean allowRestart) {
5282         int pid = app.pid;
5283         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5284                 false /*replacingPid*/);
5285         if (!kept && !restarting) {
5286             removeLruProcessLocked(app);
5287             if (pid > 0) {
5288                 ProcessList.remove(pid);
5289             }
5290         }
5291
5292         if (mProfileProc == app) {
5293             clearProfilerLocked();
5294         }
5295
5296         // Remove this application's activities from active lists.
5297         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5298
5299         app.activities.clear();
5300
5301         if (app.instr != null) {
5302             Slog.w(TAG, "Crash of app " + app.processName
5303                   + " running instrumentation " + app.instr.mClass);
5304             Bundle info = new Bundle();
5305             info.putString("shortMsg", "Process crashed.");
5306             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5307         }
5308
5309         mWindowManager.deferSurfaceLayout();
5310         try {
5311             if (!restarting && hasVisibleActivities
5312                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5313                 // If there was nothing to resume, and we are not already restarting this process, but
5314                 // there is a visible activity that is hosted by the process...  then make sure all
5315                 // visible activities are running, taking care of restarting this process.
5316                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5317             }
5318         } finally {
5319             mWindowManager.continueSurfaceLayout();
5320         }
5321     }
5322
5323     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5324         final IBinder threadBinder = thread.asBinder();
5325         // Find the application record.
5326         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5327             final ProcessRecord rec = mLruProcesses.get(i);
5328             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5329                 return i;
5330             }
5331         }
5332         return -1;
5333     }
5334
5335     final ProcessRecord getRecordForAppLocked(
5336             IApplicationThread thread) {
5337         if (thread == null) {
5338             return null;
5339         }
5340
5341         int appIndex = getLRURecordIndexForAppLocked(thread);
5342         if (appIndex >= 0) {
5343             return mLruProcesses.get(appIndex);
5344         }
5345
5346         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5347         // double-check that.
5348         final IBinder threadBinder = thread.asBinder();
5349         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5350         for (int i = pmap.size()-1; i >= 0; i--) {
5351             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5352             for (int j = procs.size()-1; j >= 0; j--) {
5353                 final ProcessRecord proc = procs.valueAt(j);
5354                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5355                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5356                             + proc);
5357                     return proc;
5358                 }
5359             }
5360         }
5361
5362         return null;
5363     }
5364
5365     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5366         // If there are no longer any background processes running,
5367         // and the app that died was not running instrumentation,
5368         // then tell everyone we are now low on memory.
5369         boolean haveBg = false;
5370         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5371             ProcessRecord rec = mLruProcesses.get(i);
5372             if (rec.thread != null
5373                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5374                 haveBg = true;
5375                 break;
5376             }
5377         }
5378
5379         if (!haveBg) {
5380             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5381             if (doReport) {
5382                 long now = SystemClock.uptimeMillis();
5383                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5384                     doReport = false;
5385                 } else {
5386                     mLastMemUsageReportTime = now;
5387                 }
5388             }
5389             final ArrayList<ProcessMemInfo> memInfos
5390                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5391             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5392             long now = SystemClock.uptimeMillis();
5393             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5394                 ProcessRecord rec = mLruProcesses.get(i);
5395                 if (rec == dyingProc || rec.thread == null) {
5396                     continue;
5397                 }
5398                 if (doReport) {
5399                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5400                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5401                 }
5402                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5403                     // The low memory report is overriding any current
5404                     // state for a GC request.  Make sure to do
5405                     // heavy/important/visible/foreground processes first.
5406                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5407                         rec.lastRequestedGc = 0;
5408                     } else {
5409                         rec.lastRequestedGc = rec.lastLowMemory;
5410                     }
5411                     rec.reportLowMemory = true;
5412                     rec.lastLowMemory = now;
5413                     mProcessesToGc.remove(rec);
5414                     addProcessToGcListLocked(rec);
5415                 }
5416             }
5417             if (doReport) {
5418                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5419                 mHandler.sendMessage(msg);
5420             }
5421             scheduleAppGcsLocked();
5422         }
5423     }
5424
5425     final void appDiedLocked(ProcessRecord app) {
5426        appDiedLocked(app, app.pid, app.thread, false);
5427     }
5428
5429     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5430             boolean fromBinderDied) {
5431         // First check if this ProcessRecord is actually active for the pid.
5432         synchronized (mPidsSelfLocked) {
5433             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5434             if (curProc != app) {
5435                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5436                 return;
5437             }
5438         }
5439
5440         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5441         synchronized (stats) {
5442             stats.noteProcessDiedLocked(app.info.uid, pid);
5443         }
5444
5445         if (!app.killed) {
5446             if (!fromBinderDied) {
5447                 killProcessQuiet(pid);
5448             }
5449             killProcessGroup(app.uid, pid);
5450             app.killed = true;
5451         }
5452
5453         // Clean up already done if the process has been re-started.
5454         if (app.pid == pid && app.thread != null &&
5455                 app.thread.asBinder() == thread.asBinder()) {
5456             boolean doLowMem = app.instr == null;
5457             boolean doOomAdj = doLowMem;
5458             if (!app.killedByAm) {
5459                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5460                         + ProcessList.makeOomAdjString(app.setAdj)
5461                         + ProcessList.makeProcStateString(app.setProcState));
5462                 mAllowLowerMemLevel = true;
5463             } else {
5464                 // Note that we always want to do oom adj to update our state with the
5465                 // new number of procs.
5466                 mAllowLowerMemLevel = false;
5467                 doLowMem = false;
5468             }
5469             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5470                     app.setAdj, app.setProcState);
5471             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5472                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5473             handleAppDiedLocked(app, false, true);
5474
5475             if (doOomAdj) {
5476                 updateOomAdjLocked();
5477             }
5478             if (doLowMem) {
5479                 doLowMemReportIfNeededLocked(app);
5480             }
5481         } else if (app.pid != pid) {
5482             // A new process has already been started.
5483             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5484                     + ") has died and restarted (pid " + app.pid + ").");
5485             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5486         } else if (DEBUG_PROCESSES) {
5487             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5488                     + thread.asBinder());
5489         }
5490     }
5491
5492     /**
5493      * If a stack trace dump file is configured, dump process stack traces.
5494      * @param clearTraces causes the dump file to be erased prior to the new
5495      *    traces being written, if true; when false, the new traces will be
5496      *    appended to any existing file content.
5497      * @param firstPids of dalvik VM processes to dump stack traces for first
5498      * @param lastPids of dalvik VM processes to dump stack traces for last
5499      * @param nativePids optional list of native pids to dump stack crawls
5500      */
5501     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5502             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5503             ArrayList<Integer> nativePids) {
5504         ArrayList<Integer> extraPids = null;
5505
5506         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5507         // of the top users at the time of the request.
5508         if (processCpuTracker != null) {
5509             processCpuTracker.init();
5510             try {
5511                 Thread.sleep(200);
5512             } catch (InterruptedException ignored) {
5513             }
5514
5515             processCpuTracker.update();
5516
5517             // We'll take the stack crawls of just the top apps using CPU.
5518             final int N = processCpuTracker.countWorkingStats();
5519             extraPids = new ArrayList<>();
5520             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5521                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5522                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5523                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5524
5525                     extraPids.add(stats.pid);
5526                 } else if (DEBUG_ANR) {
5527                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5528                             + stats.pid);
5529                 }
5530             }
5531         }
5532
5533         boolean useTombstonedForJavaTraces = false;
5534         File tracesFile;
5535
5536         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5537         if (tracesDirProp.isEmpty()) {
5538             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5539             // dumping scheme. All traces are written to a global trace file (usually
5540             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5541             // the file if requested.
5542             //
5543             // This mode of operation will be removed in the near future.
5544
5545
5546             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5547             if (globalTracesPath.isEmpty()) {
5548                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5549                 return null;
5550             }
5551
5552             tracesFile = new File(globalTracesPath);
5553             try {
5554                 if (clearTraces && tracesFile.exists()) {
5555                     tracesFile.delete();
5556                 }
5557
5558                 tracesFile.createNewFile();
5559                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5560             } catch (IOException e) {
5561                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5562                 return null;
5563             }
5564         } else {
5565             File tracesDir = new File(tracesDirProp);
5566             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5567             // Each set of ANR traces is written to a separate file and dumpstate will process
5568             // all such files and add them to a captured bug report if they're recent enough.
5569             maybePruneOldTraces(tracesDir);
5570
5571             // NOTE: We should consider creating the file in native code atomically once we've
5572             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5573             // can be removed.
5574             tracesFile = createAnrDumpFile(tracesDir);
5575             if (tracesFile == null) {
5576                 return null;
5577             }
5578
5579             useTombstonedForJavaTraces = true;
5580         }
5581
5582         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5583                 useTombstonedForJavaTraces);
5584         return tracesFile;
5585     }
5586
5587     @GuardedBy("ActivityManagerService.class")
5588     private static SimpleDateFormat sAnrFileDateFormat;
5589
5590     private static synchronized File createAnrDumpFile(File tracesDir) {
5591         if (sAnrFileDateFormat == null) {
5592             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5593         }
5594
5595         final String formattedDate = sAnrFileDateFormat.format(new Date());
5596         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5597
5598         try {
5599             if (anrFile.createNewFile()) {
5600                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5601                 return anrFile;
5602             } else {
5603                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5604             }
5605         } catch (IOException ioe) {
5606             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5607         }
5608
5609         return null;
5610     }
5611
5612     /**
5613      * Prune all trace files that are more than a day old.
5614      *
5615      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5616      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5617      * since it's the system_server that creates trace files for most ANRs.
5618      */
5619     private static void maybePruneOldTraces(File tracesDir) {
5620         final long now = System.currentTimeMillis();
5621         final File[] traceFiles = tracesDir.listFiles();
5622
5623         if (traceFiles != null) {
5624             for (File file : traceFiles) {
5625                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5626                     if (!file.delete()) {
5627                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
5628                     }
5629                 }
5630             }
5631         }
5632     }
5633
5634     /**
5635      * Legacy code, do not use. Existing users will be deleted.
5636      *
5637      * @deprecated
5638      */
5639     @Deprecated
5640     public static class DumpStackFileObserver extends FileObserver {
5641         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5642         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5643
5644         private final String mTracesPath;
5645         private boolean mClosed;
5646
5647         public DumpStackFileObserver(String tracesPath) {
5648             super(tracesPath, FileObserver.CLOSE_WRITE);
5649             mTracesPath = tracesPath;
5650         }
5651
5652         @Override
5653         public synchronized void onEvent(int event, String path) {
5654             mClosed = true;
5655             notify();
5656         }
5657
5658         public long dumpWithTimeout(int pid, long timeout) {
5659             sendSignal(pid, SIGNAL_QUIT);
5660             final long start = SystemClock.elapsedRealtime();
5661
5662             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5663             synchronized (this) {
5664                 try {
5665                     wait(waitTime); // Wait for traces file to be closed.
5666                 } catch (InterruptedException e) {
5667                     Slog.wtf(TAG, e);
5668                 }
5669             }
5670
5671             // This avoids a corner case of passing a negative time to the native
5672             // trace in case we've already hit the overall timeout.
5673             final long timeWaited = SystemClock.elapsedRealtime() - start;
5674             if (timeWaited >= timeout) {
5675                 return timeWaited;
5676             }
5677
5678             if (!mClosed) {
5679                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5680                        ". Attempting native stack collection.");
5681
5682                 final long nativeDumpTimeoutMs = Math.min(
5683                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5684
5685                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5686                         (int) (nativeDumpTimeoutMs / 1000));
5687             }
5688
5689             final long end = SystemClock.elapsedRealtime();
5690             mClosed = false;
5691
5692             return (end - start);
5693         }
5694     }
5695
5696     /**
5697      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5698      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5699      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5700      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5701      * capturing traces.
5702      */
5703     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5704         final long timeStart = SystemClock.elapsedRealtime();
5705         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5706             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5707                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5708         }
5709
5710         return SystemClock.elapsedRealtime() - timeStart;
5711     }
5712
5713     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5714             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5715             boolean useTombstonedForJavaTraces) {
5716
5717         // We don't need any sort of inotify based monitoring when we're dumping traces via
5718         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5719         // control of all writes to the file in question.
5720         final DumpStackFileObserver observer;
5721         if (useTombstonedForJavaTraces) {
5722             observer = null;
5723         } else {
5724             // Use a FileObserver to detect when traces finish writing.
5725             // The order of traces is considered important to maintain for legibility.
5726             observer = new DumpStackFileObserver(tracesFile);
5727         }
5728
5729         // We must complete all stack dumps within 20 seconds.
5730         long remainingTime = 20 * 1000;
5731         try {
5732             if (observer != null) {
5733                 observer.startWatching();
5734             }
5735
5736             // First collect all of the stacks of the most important pids.
5737             if (firstPids != null) {
5738                 int num = firstPids.size();
5739                 for (int i = 0; i < num; i++) {
5740                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5741                             + firstPids.get(i));
5742                     final long timeTaken;
5743                     if (useTombstonedForJavaTraces) {
5744                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5745                     } else {
5746                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5747                     }
5748
5749                     remainingTime -= timeTaken;
5750                     if (remainingTime <= 0) {
5751                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5752                             "); deadline exceeded.");
5753                         return;
5754                     }
5755
5756                     if (DEBUG_ANR) {
5757                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5758                     }
5759                 }
5760             }
5761
5762             // Next collect the stacks of the native pids
5763             if (nativePids != null) {
5764                 for (int pid : nativePids) {
5765                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5766                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5767
5768                     final long start = SystemClock.elapsedRealtime();
5769                     Debug.dumpNativeBacktraceToFileTimeout(
5770                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5771                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5772
5773                     remainingTime -= timeTaken;
5774                     if (remainingTime <= 0) {
5775                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5776                             "); deadline exceeded.");
5777                         return;
5778                     }
5779
5780                     if (DEBUG_ANR) {
5781                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5782                     }
5783                 }
5784             }
5785
5786             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5787             if (extraPids != null) {
5788                 for (int pid : extraPids) {
5789                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5790
5791                     final long timeTaken;
5792                     if (useTombstonedForJavaTraces) {
5793                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5794                     } else {
5795                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5796                     }
5797
5798                     remainingTime -= timeTaken;
5799                     if (remainingTime <= 0) {
5800                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5801                                 "); deadline exceeded.");
5802                         return;
5803                     }
5804
5805                     if (DEBUG_ANR) {
5806                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5807                     }
5808                 }
5809             }
5810         } finally {
5811             if (observer != null) {
5812                 observer.stopWatching();
5813             }
5814         }
5815     }
5816
5817     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5818         if (true || Build.IS_USER) {
5819             return;
5820         }
5821         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5822         if (tracesPath == null || tracesPath.length() == 0) {
5823             return;
5824         }
5825
5826         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5827         StrictMode.allowThreadDiskWrites();
5828         try {
5829             final File tracesFile = new File(tracesPath);
5830             final File tracesDir = tracesFile.getParentFile();
5831             final File tracesTmp = new File(tracesDir, "__tmp__");
5832             try {
5833                 if (tracesFile.exists()) {
5834                     tracesTmp.delete();
5835                     tracesFile.renameTo(tracesTmp);
5836                 }
5837                 StringBuilder sb = new StringBuilder();
5838                 Time tobj = new Time();
5839                 tobj.set(System.currentTimeMillis());
5840                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5841                 sb.append(": ");
5842                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5843                 sb.append(" since ");
5844                 sb.append(msg);
5845                 FileOutputStream fos = new FileOutputStream(tracesFile);
5846                 fos.write(sb.toString().getBytes());
5847                 if (app == null) {
5848                     fos.write("\n*** No application process!".getBytes());
5849                 }
5850                 fos.close();
5851                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5852             } catch (IOException e) {
5853                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5854                 return;
5855             }
5856
5857             if (app != null) {
5858                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5859                 firstPids.add(app.pid);
5860                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5861             }
5862
5863             File lastTracesFile = null;
5864             File curTracesFile = null;
5865             for (int i=9; i>=0; i--) {
5866                 String name = String.format(Locale.US, "slow%02d.txt", i);
5867                 curTracesFile = new File(tracesDir, name);
5868                 if (curTracesFile.exists()) {
5869                     if (lastTracesFile != null) {
5870                         curTracesFile.renameTo(lastTracesFile);
5871                     } else {
5872                         curTracesFile.delete();
5873                     }
5874                 }
5875                 lastTracesFile = curTracesFile;
5876             }
5877             tracesFile.renameTo(curTracesFile);
5878             if (tracesTmp.exists()) {
5879                 tracesTmp.renameTo(tracesFile);
5880             }
5881         } finally {
5882             StrictMode.setThreadPolicy(oldPolicy);
5883         }
5884     }
5885
5886     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5887         if (!mLaunchWarningShown) {
5888             mLaunchWarningShown = true;
5889             mUiHandler.post(new Runnable() {
5890                 @Override
5891                 public void run() {
5892                     synchronized (ActivityManagerService.this) {
5893                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5894                         d.show();
5895                         mUiHandler.postDelayed(new Runnable() {
5896                             @Override
5897                             public void run() {
5898                                 synchronized (ActivityManagerService.this) {
5899                                     d.dismiss();
5900                                     mLaunchWarningShown = false;
5901                                 }
5902                             }
5903                         }, 4000);
5904                     }
5905                 }
5906             });
5907         }
5908     }
5909
5910     @Override
5911     public boolean clearApplicationUserData(final String packageName,
5912             final IPackageDataObserver observer, int userId) {
5913         enforceNotIsolatedCaller("clearApplicationUserData");
5914         int uid = Binder.getCallingUid();
5915         int pid = Binder.getCallingPid();
5916         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5917                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5918
5919         final ApplicationInfo appInfo;
5920         final boolean isInstantApp;
5921
5922         long callingId = Binder.clearCallingIdentity();
5923         try {
5924             IPackageManager pm = AppGlobals.getPackageManager();
5925             synchronized(this) {
5926                 // Instant packages are not protected
5927                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5928                         resolvedUserId, packageName)) {
5929                     throw new SecurityException(
5930                             "Cannot clear data for a protected package: " + packageName);
5931                 }
5932
5933                 ApplicationInfo applicationInfo = null;
5934                 try {
5935                     applicationInfo = pm.getApplicationInfo(packageName,
5936                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5937                 } catch (RemoteException e) {
5938                     /* ignore */
5939                 }
5940                 appInfo = applicationInfo;
5941
5942                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5943
5944                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5945                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5946                     throw new SecurityException("PID " + pid + " does not have permission "
5947                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5948                             + " of package " + packageName);
5949                 }
5950
5951                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5952                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
5953                 final boolean isUninstalledAppWithoutInstantMetadata =
5954                         (appInfo == null && !hasInstantMetadata);
5955                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5956                         || hasInstantMetadata;
5957                 final boolean canAccessInstantApps = checkComponentPermission(
5958                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5959                         == PackageManager.PERMISSION_GRANTED;
5960
5961                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5962                         && !canAccessInstantApps)) {
5963                     Slog.w(TAG, "Invalid packageName: " + packageName);
5964                     if (observer != null) {
5965                         try {
5966                             observer.onRemoveCompleted(packageName, false);
5967                         } catch (RemoteException e) {
5968                             Slog.i(TAG, "Observer no longer exists.");
5969                         }
5970                     }
5971                     return false;
5972                 }
5973
5974                 if (appInfo != null) {
5975                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5976                     // Remove all tasks match the cleared application package and user
5977                     for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5978                         final TaskRecord tr = mRecentTasks.get(i);
5979                         final String taskPackageName =
5980                                 tr.getBaseIntent().getComponent().getPackageName();
5981                         if (tr.userId != resolvedUserId) continue;
5982                         if (!taskPackageName.equals(packageName)) continue;
5983                         mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5984                                 REMOVE_FROM_RECENTS);
5985                     }
5986                 }
5987             }
5988
5989             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5990                 @Override
5991                 public void onRemoveCompleted(String packageName, boolean succeeded)
5992                         throws RemoteException {
5993                     if (appInfo != null) {
5994                         synchronized (ActivityManagerService.this) {
5995                             finishForceStopPackageLocked(packageName, appInfo.uid);
5996                         }
5997                     }
5998                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5999                             Uri.fromParts("package", packageName, null));
6000                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6001                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6002                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6003                     if (isInstantApp) {
6004                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6005                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6006                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6007                                 resolvedUserId);
6008                     } else {
6009                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6010                                 null, null, null, null, false, false, resolvedUserId);
6011                     }
6012
6013                     if (observer != null) {
6014                         observer.onRemoveCompleted(packageName, succeeded);
6015                     }
6016                 }
6017             };
6018
6019             try {
6020                 // Clear application user data
6021                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6022
6023                 if (appInfo != null) {
6024                     synchronized (this) {
6025                         // Remove all permissions granted from/to this package
6026                         removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6027                     }
6028
6029                     // Reset notification settings.
6030                     INotificationManager inm = NotificationManager.getService();
6031                     inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6032                 }
6033             } catch (RemoteException e) {
6034             }
6035         } finally {
6036             Binder.restoreCallingIdentity(callingId);
6037         }
6038         return true;
6039     }
6040
6041     @Override
6042     public void killBackgroundProcesses(final String packageName, int userId) {
6043         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6044                 != PackageManager.PERMISSION_GRANTED &&
6045                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6046                         != PackageManager.PERMISSION_GRANTED) {
6047             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6048                     + Binder.getCallingPid()
6049                     + ", uid=" + Binder.getCallingUid()
6050                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6051             Slog.w(TAG, msg);
6052             throw new SecurityException(msg);
6053         }
6054
6055         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6056                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6057         long callingId = Binder.clearCallingIdentity();
6058         try {
6059             IPackageManager pm = AppGlobals.getPackageManager();
6060             synchronized(this) {
6061                 int appId = -1;
6062                 try {
6063                     appId = UserHandle.getAppId(
6064                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6065                 } catch (RemoteException e) {
6066                 }
6067                 if (appId == -1) {
6068                     Slog.w(TAG, "Invalid packageName: " + packageName);
6069                     return;
6070                 }
6071                 killPackageProcessesLocked(packageName, appId, userId,
6072                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6073             }
6074         } finally {
6075             Binder.restoreCallingIdentity(callingId);
6076         }
6077     }
6078
6079     @Override
6080     public void killAllBackgroundProcesses() {
6081         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6082                 != PackageManager.PERMISSION_GRANTED) {
6083             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6084                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6085                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6086             Slog.w(TAG, msg);
6087             throw new SecurityException(msg);
6088         }
6089
6090         final long callingId = Binder.clearCallingIdentity();
6091         try {
6092             synchronized (this) {
6093                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6094                 final int NP = mProcessNames.getMap().size();
6095                 for (int ip = 0; ip < NP; ip++) {
6096                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6097                     final int NA = apps.size();
6098                     for (int ia = 0; ia < NA; ia++) {
6099                         final ProcessRecord app = apps.valueAt(ia);
6100                         if (app.persistent) {
6101                             // We don't kill persistent processes.
6102                             continue;
6103                         }
6104                         if (app.removed) {
6105                             procs.add(app);
6106                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6107                             app.removed = true;
6108                             procs.add(app);
6109                         }
6110                     }
6111                 }
6112
6113                 final int N = procs.size();
6114                 for (int i = 0; i < N; i++) {
6115                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6116                 }
6117
6118                 mAllowLowerMemLevel = true;
6119
6120                 updateOomAdjLocked();
6121                 doLowMemReportIfNeededLocked(null);
6122             }
6123         } finally {
6124             Binder.restoreCallingIdentity(callingId);
6125         }
6126     }
6127
6128     /**
6129      * Kills all background processes, except those matching any of the
6130      * specified properties.
6131      *
6132      * @param minTargetSdk the target SDK version at or above which to preserve
6133      *                     processes, or {@code -1} to ignore the target SDK
6134      * @param maxProcState the process state at or below which to preserve
6135      *                     processes, or {@code -1} to ignore the process state
6136      */
6137     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6138         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6139                 != PackageManager.PERMISSION_GRANTED) {
6140             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6141                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6142                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6143             Slog.w(TAG, msg);
6144             throw new SecurityException(msg);
6145         }
6146
6147         final long callingId = Binder.clearCallingIdentity();
6148         try {
6149             synchronized (this) {
6150                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6151                 final int NP = mProcessNames.getMap().size();
6152                 for (int ip = 0; ip < NP; ip++) {
6153                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6154                     final int NA = apps.size();
6155                     for (int ia = 0; ia < NA; ia++) {
6156                         final ProcessRecord app = apps.valueAt(ia);
6157                         if (app.removed) {
6158                             procs.add(app);
6159                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6160                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6161                             app.removed = true;
6162                             procs.add(app);
6163                         }
6164                     }
6165                 }
6166
6167                 final int N = procs.size();
6168                 for (int i = 0; i < N; i++) {
6169                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6170                 }
6171             }
6172         } finally {
6173             Binder.restoreCallingIdentity(callingId);
6174         }
6175     }
6176
6177     @Override
6178     public void forceStopPackage(final String packageName, int userId) {
6179         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6180                 != PackageManager.PERMISSION_GRANTED) {
6181             String msg = "Permission Denial: forceStopPackage() from pid="
6182                     + Binder.getCallingPid()
6183                     + ", uid=" + Binder.getCallingUid()
6184                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6185             Slog.w(TAG, msg);
6186             throw new SecurityException(msg);
6187         }
6188         final int callingPid = Binder.getCallingPid();
6189         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6190                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6191         long callingId = Binder.clearCallingIdentity();
6192         try {
6193             IPackageManager pm = AppGlobals.getPackageManager();
6194             synchronized(this) {
6195                 int[] users = userId == UserHandle.USER_ALL
6196                         ? mUserController.getUsers() : new int[] { userId };
6197                 for (int user : users) {
6198                     int pkgUid = -1;
6199                     try {
6200                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6201                                 user);
6202                     } catch (RemoteException e) {
6203                     }
6204                     if (pkgUid == -1) {
6205                         Slog.w(TAG, "Invalid packageName: " + packageName);
6206                         continue;
6207                     }
6208                     try {
6209                         pm.setPackageStoppedState(packageName, true, user);
6210                     } catch (RemoteException e) {
6211                     } catch (IllegalArgumentException e) {
6212                         Slog.w(TAG, "Failed trying to unstop package "
6213                                 + packageName + ": " + e);
6214                     }
6215                     if (mUserController.isUserRunningLocked(user, 0)) {
6216                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6217                         finishForceStopPackageLocked(packageName, pkgUid);
6218                     }
6219                 }
6220             }
6221         } finally {
6222             Binder.restoreCallingIdentity(callingId);
6223         }
6224     }
6225
6226     @Override
6227     public void addPackageDependency(String packageName) {
6228         synchronized (this) {
6229             int callingPid = Binder.getCallingPid();
6230             if (callingPid == myPid()) {
6231                 //  Yeah, um, no.
6232                 return;
6233             }
6234             ProcessRecord proc;
6235             synchronized (mPidsSelfLocked) {
6236                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6237             }
6238             if (proc != null) {
6239                 if (proc.pkgDeps == null) {
6240                     proc.pkgDeps = new ArraySet<String>(1);
6241                 }
6242                 proc.pkgDeps.add(packageName);
6243             }
6244         }
6245     }
6246
6247     /*
6248      * The pkg name and app id have to be specified.
6249      */
6250     @Override
6251     public void killApplication(String pkg, int appId, int userId, String reason) {
6252         if (pkg == null) {
6253             return;
6254         }
6255         // Make sure the uid is valid.
6256         if (appId < 0) {
6257             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6258             return;
6259         }
6260         int callerUid = Binder.getCallingUid();
6261         // Only the system server can kill an application
6262         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6263             // Post an aysnc message to kill the application
6264             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6265             msg.arg1 = appId;
6266             msg.arg2 = userId;
6267             Bundle bundle = new Bundle();
6268             bundle.putString("pkg", pkg);
6269             bundle.putString("reason", reason);
6270             msg.obj = bundle;
6271             mHandler.sendMessage(msg);
6272         } else {
6273             throw new SecurityException(callerUid + " cannot kill pkg: " +
6274                     pkg);
6275         }
6276     }
6277
6278     @Override
6279     public void closeSystemDialogs(String reason) {
6280         enforceNotIsolatedCaller("closeSystemDialogs");
6281
6282         final int pid = Binder.getCallingPid();
6283         final int uid = Binder.getCallingUid();
6284         final long origId = Binder.clearCallingIdentity();
6285         try {
6286             synchronized (this) {
6287                 // Only allow this from foreground processes, so that background
6288                 // applications can't abuse it to prevent system UI from being shown.
6289                 if (uid >= FIRST_APPLICATION_UID) {
6290                     ProcessRecord proc;
6291                     synchronized (mPidsSelfLocked) {
6292                         proc = mPidsSelfLocked.get(pid);
6293                     }
6294                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6295                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6296                                 + " from background process " + proc);
6297                         return;
6298                     }
6299                 }
6300                 closeSystemDialogsLocked(reason);
6301             }
6302         } finally {
6303             Binder.restoreCallingIdentity(origId);
6304         }
6305     }
6306
6307     void closeSystemDialogsLocked(String reason) {
6308         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6309         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6310                 | Intent.FLAG_RECEIVER_FOREGROUND);
6311         if (reason != null) {
6312             intent.putExtra("reason", reason);
6313         }
6314         mWindowManager.closeSystemDialogs(reason);
6315
6316         mStackSupervisor.closeSystemDialogsLocked();
6317
6318         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6319                 AppOpsManager.OP_NONE, null, false, false,
6320                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6321     }
6322
6323     @Override
6324     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6325         enforceNotIsolatedCaller("getProcessMemoryInfo");
6326         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6327         for (int i=pids.length-1; i>=0; i--) {
6328             ProcessRecord proc;
6329             int oomAdj;
6330             synchronized (this) {
6331                 synchronized (mPidsSelfLocked) {
6332                     proc = mPidsSelfLocked.get(pids[i]);
6333                     oomAdj = proc != null ? proc.setAdj : 0;
6334                 }
6335             }
6336             infos[i] = new Debug.MemoryInfo();
6337             Debug.getMemoryInfo(pids[i], infos[i]);
6338             if (proc != null) {
6339                 synchronized (this) {
6340                     if (proc.thread != null && proc.setAdj == oomAdj) {
6341                         // Record this for posterity if the process has been stable.
6342                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6343                                 infos[i].getTotalUss(), false, proc.pkgList);
6344                     }
6345                 }
6346             }
6347         }
6348         return infos;
6349     }
6350
6351     @Override
6352     public long[] getProcessPss(int[] pids) {
6353         enforceNotIsolatedCaller("getProcessPss");
6354         long[] pss = new long[pids.length];
6355         for (int i=pids.length-1; i>=0; i--) {
6356             ProcessRecord proc;
6357             int oomAdj;
6358             synchronized (this) {
6359                 synchronized (mPidsSelfLocked) {
6360                     proc = mPidsSelfLocked.get(pids[i]);
6361                     oomAdj = proc != null ? proc.setAdj : 0;
6362                 }
6363             }
6364             long[] tmpUss = new long[1];
6365             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6366             if (proc != null) {
6367                 synchronized (this) {
6368                     if (proc.thread != null && proc.setAdj == oomAdj) {
6369                         // Record this for posterity if the process has been stable.
6370                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6371                     }
6372                 }
6373             }
6374         }
6375         return pss;
6376     }
6377
6378     @Override
6379     public void killApplicationProcess(String processName, int uid) {
6380         if (processName == null) {
6381             return;
6382         }
6383
6384         int callerUid = Binder.getCallingUid();
6385         // Only the system server can kill an application
6386         if (callerUid == SYSTEM_UID) {
6387             synchronized (this) {
6388                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6389                 if (app != null && app.thread != null) {
6390                     try {
6391                         app.thread.scheduleSuicide();
6392                     } catch (RemoteException e) {
6393                         // If the other end already died, then our work here is done.
6394                     }
6395                 } else {
6396                     Slog.w(TAG, "Process/uid not found attempting kill of "
6397                             + processName + " / " + uid);
6398                 }
6399             }
6400         } else {
6401             throw new SecurityException(callerUid + " cannot kill app process: " +
6402                     processName);
6403         }
6404     }
6405
6406     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6407         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6408                 false, true, false, false, UserHandle.getUserId(uid), reason);
6409     }
6410
6411     private void finishForceStopPackageLocked(final String packageName, int uid) {
6412         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6413                 Uri.fromParts("package", packageName, null));
6414         if (!mProcessesReady) {
6415             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6416                     | Intent.FLAG_RECEIVER_FOREGROUND);
6417         }
6418         intent.putExtra(Intent.EXTRA_UID, uid);
6419         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6420         broadcastIntentLocked(null, null, intent,
6421                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6422                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6423     }
6424
6425
6426     private final boolean killPackageProcessesLocked(String packageName, int appId,
6427             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6428             boolean doit, boolean evenPersistent, String reason) {
6429         ArrayList<ProcessRecord> procs = new ArrayList<>();
6430
6431         // Remove all processes this package may have touched: all with the
6432         // same UID (except for the system or root user), and all whose name
6433         // matches the package name.
6434         final int NP = mProcessNames.getMap().size();
6435         for (int ip=0; ip<NP; ip++) {
6436             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6437             final int NA = apps.size();
6438             for (int ia=0; ia<NA; ia++) {
6439                 ProcessRecord app = apps.valueAt(ia);
6440                 if (app.persistent && !evenPersistent) {
6441                     // we don't kill persistent processes
6442                     continue;
6443                 }
6444                 if (app.removed) {
6445                     if (doit) {
6446                         procs.add(app);
6447                     }
6448                     continue;
6449                 }
6450
6451                 // Skip process if it doesn't meet our oom adj requirement.
6452                 if (app.setAdj < minOomAdj) {
6453                     continue;
6454                 }
6455
6456                 // If no package is specified, we call all processes under the
6457                 // give user id.
6458                 if (packageName == null) {
6459                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6460                         continue;
6461                     }
6462                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6463                         continue;
6464                     }
6465                 // Package has been specified, we want to hit all processes
6466                 // that match it.  We need to qualify this by the processes
6467                 // that are running under the specified app and user ID.
6468                 } else {
6469                     final boolean isDep = app.pkgDeps != null
6470                             && app.pkgDeps.contains(packageName);
6471                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6472                         continue;
6473                     }
6474                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6475                         continue;
6476                     }
6477                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6478                         continue;
6479                     }
6480                 }
6481
6482                 // Process has passed all conditions, kill it!
6483                 if (!doit) {
6484                     return true;
6485                 }
6486                 app.removed = true;
6487                 procs.add(app);
6488             }
6489         }
6490
6491         int N = procs.size();
6492         for (int i=0; i<N; i++) {
6493             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6494         }
6495         updateOomAdjLocked();
6496         return N > 0;
6497     }
6498
6499     private void cleanupDisabledPackageComponentsLocked(
6500             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6501
6502         Set<String> disabledClasses = null;
6503         boolean packageDisabled = false;
6504         IPackageManager pm = AppGlobals.getPackageManager();
6505
6506         if (changedClasses == null) {
6507             // Nothing changed...
6508             return;
6509         }
6510
6511         // Determine enable/disable state of the package and its components.
6512         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6513         for (int i = changedClasses.length - 1; i >= 0; i--) {
6514             final String changedClass = changedClasses[i];
6515
6516             if (changedClass.equals(packageName)) {
6517                 try {
6518                     // Entire package setting changed
6519                     enabled = pm.getApplicationEnabledSetting(packageName,
6520                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6521                 } catch (Exception e) {
6522                     // No such package/component; probably racing with uninstall.  In any
6523                     // event it means we have nothing further to do here.
6524                     return;
6525                 }
6526                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6527                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6528                 if (packageDisabled) {
6529                     // Entire package is disabled.
6530                     // No need to continue to check component states.
6531                     disabledClasses = null;
6532                     break;
6533                 }
6534             } else {
6535                 try {
6536                     enabled = pm.getComponentEnabledSetting(
6537                             new ComponentName(packageName, changedClass),
6538                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6539                 } catch (Exception e) {
6540                     // As above, probably racing with uninstall.
6541                     return;
6542                 }
6543                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6544                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6545                     if (disabledClasses == null) {
6546                         disabledClasses = new ArraySet<>(changedClasses.length);
6547                     }
6548                     disabledClasses.add(changedClass);
6549                 }
6550             }
6551         }
6552
6553         if (!packageDisabled && disabledClasses == null) {
6554             // Nothing to do here...
6555             return;
6556         }
6557
6558         // Clean-up disabled activities.
6559         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6560                 packageName, disabledClasses, true, false, userId) && mBooted) {
6561             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6562             mStackSupervisor.scheduleIdleLocked();
6563         }
6564
6565         // Clean-up disabled tasks
6566         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6567
6568         // Clean-up disabled services.
6569         mServices.bringDownDisabledPackageServicesLocked(
6570                 packageName, disabledClasses, userId, false, killProcess, true);
6571
6572         // Clean-up disabled providers.
6573         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6574         mProviderMap.collectPackageProvidersLocked(
6575                 packageName, disabledClasses, true, false, userId, providers);
6576         for (int i = providers.size() - 1; i >= 0; i--) {
6577             removeDyingProviderLocked(null, providers.get(i), true);
6578         }
6579
6580         // Clean-up disabled broadcast receivers.
6581         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6582             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6583                     packageName, disabledClasses, userId, true);
6584         }
6585
6586     }
6587
6588     final boolean clearBroadcastQueueForUserLocked(int userId) {
6589         boolean didSomething = false;
6590         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6591             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6592                     null, null, userId, true);
6593         }
6594         return didSomething;
6595     }
6596
6597     final boolean forceStopPackageLocked(String packageName, int appId,
6598             boolean callerWillRestart, boolean purgeCache, boolean doit,
6599             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6600         int i;
6601
6602         if (userId == UserHandle.USER_ALL && packageName == null) {
6603             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6604         }
6605
6606         if (appId < 0 && packageName != null) {
6607             try {
6608                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6609                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6610             } catch (RemoteException e) {
6611             }
6612         }
6613
6614         if (doit) {
6615             if (packageName != null) {
6616                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6617                         + " user=" + userId + ": " + reason);
6618             } else {
6619                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6620             }
6621
6622             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6623         }
6624
6625         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6626                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6627                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6628
6629         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6630
6631         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6632                 packageName, null, doit, evenPersistent, userId)) {
6633             if (!doit) {
6634                 return true;
6635             }
6636             didSomething = true;
6637         }
6638
6639         if (mServices.bringDownDisabledPackageServicesLocked(
6640                 packageName, null, userId, evenPersistent, true, doit)) {
6641             if (!doit) {
6642                 return true;
6643             }
6644             didSomething = true;
6645         }
6646
6647         if (packageName == null) {
6648             // Remove all sticky broadcasts from this user.
6649             mStickyBroadcasts.remove(userId);
6650         }
6651
6652         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6653         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6654                 userId, providers)) {
6655             if (!doit) {
6656                 return true;
6657             }
6658             didSomething = true;
6659         }
6660         for (i = providers.size() - 1; i >= 0; i--) {
6661             removeDyingProviderLocked(null, providers.get(i), true);
6662         }
6663
6664         // Remove transient permissions granted from/to this package/user
6665         removeUriPermissionsForPackageLocked(packageName, userId, false);
6666
6667         if (doit) {
6668             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6669                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6670                         packageName, null, userId, doit);
6671             }
6672         }
6673
6674         if (packageName == null || uninstalling) {
6675             // Remove pending intents.  For now we only do this when force
6676             // stopping users, because we have some problems when doing this
6677             // for packages -- app widgets are not currently cleaned up for
6678             // such packages, so they can be left with bad pending intents.
6679             if (mIntentSenderRecords.size() > 0) {
6680                 Iterator<WeakReference<PendingIntentRecord>> it
6681                         = mIntentSenderRecords.values().iterator();
6682                 while (it.hasNext()) {
6683                     WeakReference<PendingIntentRecord> wpir = it.next();
6684                     if (wpir == null) {
6685                         it.remove();
6686                         continue;
6687                     }
6688                     PendingIntentRecord pir = wpir.get();
6689                     if (pir == null) {
6690                         it.remove();
6691                         continue;
6692                     }
6693                     if (packageName == null) {
6694                         // Stopping user, remove all objects for the user.
6695                         if (pir.key.userId != userId) {
6696                             // Not the same user, skip it.
6697                             continue;
6698                         }
6699                     } else {
6700                         if (UserHandle.getAppId(pir.uid) != appId) {
6701                             // Different app id, skip it.
6702                             continue;
6703                         }
6704                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6705                             // Different user, skip it.
6706                             continue;
6707                         }
6708                         if (!pir.key.packageName.equals(packageName)) {
6709                             // Different package, skip it.
6710                             continue;
6711                         }
6712                     }
6713                     if (!doit) {
6714                         return true;
6715                     }
6716                     didSomething = true;
6717                     it.remove();
6718                     makeIntentSenderCanceledLocked(pir);
6719                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6720                         pir.key.activity.pendingResults.remove(pir.ref);
6721                     }
6722                 }
6723             }
6724         }
6725
6726         if (doit) {
6727             if (purgeCache && packageName != null) {
6728                 AttributeCache ac = AttributeCache.instance();
6729                 if (ac != null) {
6730                     ac.removePackage(packageName);
6731                 }
6732             }
6733             if (mBooted) {
6734                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6735                 mStackSupervisor.scheduleIdleLocked();
6736             }
6737         }
6738
6739         return didSomething;
6740     }
6741
6742     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6743         return removeProcessNameLocked(name, uid, null);
6744     }
6745
6746     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6747             final ProcessRecord expecting) {
6748         ProcessRecord old = mProcessNames.get(name, uid);
6749         // Only actually remove when the currently recorded value matches the
6750         // record that we expected; if it doesn't match then we raced with a
6751         // newly created process and we don't want to destroy the new one.
6752         if ((expecting == null) || (old == expecting)) {
6753             mProcessNames.remove(name, uid);
6754         }
6755         if (old != null && old.uidRecord != null) {
6756             old.uidRecord.numProcs--;
6757             if (old.uidRecord.numProcs == 0) {
6758                 // No more processes using this uid, tell clients it is gone.
6759                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6760                         "No more processes in " + old.uidRecord);
6761                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6762                 EventLogTags.writeAmUidStopped(uid);
6763                 mActiveUids.remove(uid);
6764                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6765             }
6766             old.uidRecord = null;
6767         }
6768         mIsolatedProcesses.remove(uid);
6769         return old;
6770     }
6771
6772     private final void addProcessNameLocked(ProcessRecord proc) {
6773         // We shouldn't already have a process under this name, but just in case we
6774         // need to clean up whatever may be there now.
6775         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6776         if (old == proc && proc.persistent) {
6777             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6778             Slog.w(TAG, "Re-adding persistent process " + proc);
6779         } else if (old != null) {
6780             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6781         }
6782         UidRecord uidRec = mActiveUids.get(proc.uid);
6783         if (uidRec == null) {
6784             uidRec = new UidRecord(proc.uid);
6785             // This is the first appearance of the uid, report it now!
6786             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6787                     "Creating new process uid: " + uidRec);
6788             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6789                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6790                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6791             }
6792             uidRec.updateHasInternetPermission();
6793             mActiveUids.put(proc.uid, uidRec);
6794             EventLogTags.writeAmUidRunning(uidRec.uid);
6795             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6796         }
6797         proc.uidRecord = uidRec;
6798
6799         // Reset render thread tid if it was already set, so new process can set it again.
6800         proc.renderThreadTid = 0;
6801         uidRec.numProcs++;
6802         mProcessNames.put(proc.processName, proc.uid, proc);
6803         if (proc.isolated) {
6804             mIsolatedProcesses.put(proc.uid, proc);
6805         }
6806     }
6807
6808     boolean removeProcessLocked(ProcessRecord app,
6809             boolean callerWillRestart, boolean allowRestart, String reason) {
6810         final String name = app.processName;
6811         final int uid = app.uid;
6812         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6813             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6814
6815         ProcessRecord old = mProcessNames.get(name, uid);
6816         if (old != app) {
6817             // This process is no longer active, so nothing to do.
6818             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6819             return false;
6820         }
6821         removeProcessNameLocked(name, uid);
6822         if (mHeavyWeightProcess == app) {
6823             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6824                     mHeavyWeightProcess.userId, 0));
6825             mHeavyWeightProcess = null;
6826         }
6827         boolean needRestart = false;
6828         if (app.pid > 0 && app.pid != MY_PID) {
6829             int pid = app.pid;
6830             synchronized (mPidsSelfLocked) {
6831                 mPidsSelfLocked.remove(pid);
6832                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6833             }
6834             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6835             boolean willRestart = false;
6836             if (app.persistent && !app.isolated) {
6837                 if (!callerWillRestart) {
6838                     willRestart = true;
6839                 } else {
6840                     needRestart = true;
6841                 }
6842             }
6843             app.kill(reason, true);
6844             if (app.isolated) {
6845                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6846                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6847             }
6848             handleAppDiedLocked(app, willRestart, allowRestart);
6849             if (willRestart) {
6850                 removeLruProcessLocked(app);
6851                 addAppLocked(app.info, null, false, null /* ABI override */);
6852             }
6853         } else {
6854             mRemovedProcesses.add(app);
6855         }
6856
6857         return needRestart;
6858     }
6859
6860     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6861         cleanupAppInLaunchingProvidersLocked(app, true);
6862         removeProcessLocked(app, false, true, "timeout publishing content providers");
6863     }
6864
6865     private final void processStartTimedOutLocked(ProcessRecord app) {
6866         final int pid = app.pid;
6867         boolean gone = false;
6868         synchronized (mPidsSelfLocked) {
6869             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6870             if (knownApp != null && knownApp.thread == null) {
6871                 mPidsSelfLocked.remove(pid);
6872                 gone = true;
6873             }
6874         }
6875
6876         if (gone) {
6877             Slog.w(TAG, "Process " + app + " failed to attach");
6878             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6879                     pid, app.uid, app.processName);
6880             removeProcessNameLocked(app.processName, app.uid);
6881             if (mHeavyWeightProcess == app) {
6882                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6883                         mHeavyWeightProcess.userId, 0));
6884                 mHeavyWeightProcess = null;
6885             }
6886             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6887             // Take care of any launching providers waiting for this process.
6888             cleanupAppInLaunchingProvidersLocked(app, true);
6889             // Take care of any services that are waiting for the process.
6890             mServices.processStartTimedOutLocked(app);
6891             app.kill("start timeout", true);
6892             if (app.isolated) {
6893                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6894             }
6895             removeLruProcessLocked(app);
6896             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6897                 Slog.w(TAG, "Unattached app died before backup, skipping");
6898                 mHandler.post(new Runnable() {
6899                 @Override
6900                     public void run(){
6901                         try {
6902                             IBackupManager bm = IBackupManager.Stub.asInterface(
6903                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6904                             bm.agentDisconnected(app.info.packageName);
6905                         } catch (RemoteException e) {
6906                             // Can't happen; the backup manager is local
6907                         }
6908                     }
6909                 });
6910             }
6911             if (isPendingBroadcastProcessLocked(pid)) {
6912                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6913                 skipPendingBroadcastLocked(pid);
6914             }
6915         } else {
6916             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6917         }
6918     }
6919
6920     private final boolean attachApplicationLocked(IApplicationThread thread,
6921             int pid) {
6922
6923         // Find the application record that is being attached...  either via
6924         // the pid if we are running in multiple processes, or just pull the
6925         // next app record if we are emulating process with anonymous threads.
6926         ProcessRecord app;
6927         long startTime = SystemClock.uptimeMillis();
6928         if (pid != MY_PID && pid >= 0) {
6929             synchronized (mPidsSelfLocked) {
6930                 app = mPidsSelfLocked.get(pid);
6931             }
6932         } else {
6933             app = null;
6934         }
6935
6936         if (app == null) {
6937             Slog.w(TAG, "No pending application record for pid " + pid
6938                     + " (IApplicationThread " + thread + "); dropping process");
6939             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6940             if (pid > 0 && pid != MY_PID) {
6941                 killProcessQuiet(pid);
6942                 //TODO: killProcessGroup(app.info.uid, pid);
6943             } else {
6944                 try {
6945                     thread.scheduleExit();
6946                 } catch (Exception e) {
6947                     // Ignore exceptions.
6948                 }
6949             }
6950             return false;
6951         }
6952
6953         // If this application record is still attached to a previous
6954         // process, clean it up now.
6955         if (app.thread != null) {
6956             handleAppDiedLocked(app, true, true);
6957         }
6958
6959         // Tell the process all about itself.
6960
6961         if (DEBUG_ALL) Slog.v(
6962                 TAG, "Binding process pid " + pid + " to record " + app);
6963
6964         final String processName = app.processName;
6965         try {
6966             AppDeathRecipient adr = new AppDeathRecipient(
6967                     app, pid, thread);
6968             thread.asBinder().linkToDeath(adr, 0);
6969             app.deathRecipient = adr;
6970         } catch (RemoteException e) {
6971             app.resetPackageList(mProcessStats);
6972             startProcessLocked(app, "link fail", processName);
6973             return false;
6974         }
6975
6976         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6977
6978         app.makeActive(thread, mProcessStats);
6979         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6980         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6981         app.forcingToImportant = null;
6982         updateProcessForegroundLocked(app, false, false);
6983         app.hasShownUi = false;
6984         app.debugging = false;
6985         app.cached = false;
6986         app.killedByAm = false;
6987         app.killed = false;
6988
6989
6990         // We carefully use the same state that PackageManager uses for
6991         // filtering, since we use this flag to decide if we need to install
6992         // providers when user is unlocked later
6993         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6994
6995         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6996
6997         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6998         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6999
7000         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7001             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7002             msg.obj = app;
7003             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7004         }
7005
7006         checkTime(startTime, "attachApplicationLocked: before bindApplication");
7007
7008         if (!normalMode) {
7009             Slog.i(TAG, "Launching preboot mode app: " + app);
7010         }
7011
7012         if (DEBUG_ALL) Slog.v(
7013             TAG, "New app record " + app
7014             + " thread=" + thread.asBinder() + " pid=" + pid);
7015         try {
7016             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7017             if (mDebugApp != null && mDebugApp.equals(processName)) {
7018                 testMode = mWaitForDebugger
7019                     ? ApplicationThreadConstants.DEBUG_WAIT
7020                     : ApplicationThreadConstants.DEBUG_ON;
7021                 app.debugging = true;
7022                 if (mDebugTransient) {
7023                     mDebugApp = mOrigDebugApp;
7024                     mWaitForDebugger = mOrigWaitForDebugger;
7025                 }
7026             }
7027
7028             boolean enableTrackAllocation = false;
7029             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7030                 enableTrackAllocation = true;
7031                 mTrackAllocationApp = null;
7032             }
7033
7034             // If the app is being launched for restore or full backup, set it up specially
7035             boolean isRestrictedBackupMode = false;
7036             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7037                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7038                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7039                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7040                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7041             }
7042
7043             if (app.instr != null) {
7044                 notifyPackageUse(app.instr.mClass.getPackageName(),
7045                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7046             }
7047             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7048                     + processName + " with config " + getGlobalConfiguration());
7049             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7050             app.compat = compatibilityInfoForPackageLocked(appInfo);
7051
7052             ProfilerInfo profilerInfo = null;
7053             String preBindAgent = null;
7054             if (mProfileApp != null && mProfileApp.equals(processName)) {
7055                 mProfileProc = app;
7056                 if (mProfilerInfo != null) {
7057                     // Send a profiler info object to the app if either a file is given, or
7058                     // an agent should be loaded at bind-time.
7059                     boolean needsInfo = mProfilerInfo.profileFile != null
7060                             || mProfilerInfo.attachAgentDuringBind;
7061                     profilerInfo = needsInfo ? new ProfilerInfo(mProfilerInfo) : null;
7062                     if (mProfilerInfo.agent != null) {
7063                         preBindAgent = mProfilerInfo.agent;
7064                     }
7065                 }
7066             } else if (app.instr != null && app.instr.mProfileFile != null) {
7067                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7068                         null, false);
7069             }
7070             if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) {
7071                 // We need to do a debuggable check here. See setAgentApp for why the check is
7072                 // postponed to here.
7073                 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
7074                     String agent = mAppAgentMap.get(processName);
7075                     // Do not overwrite already requested agent.
7076                     if (profilerInfo == null) {
7077                         profilerInfo = new ProfilerInfo(null, null, 0, false, false,
7078                                 mAppAgentMap.get(processName), true);
7079                     } else if (profilerInfo.agent == null) {
7080                         profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true);
7081                     }
7082                 }
7083             }
7084
7085             if (profilerInfo != null && profilerInfo.profileFd != null) {
7086                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7087             }
7088
7089             // We deprecated Build.SERIAL and it is not accessible to
7090             // apps that target the v2 security sandbox. Since access to
7091             // the serial is now behind a permission we push down the value.
7092             String buildSerial = appInfo.targetSandboxVersion < 2
7093                     ? sTheRealBuildSerial : Build.UNKNOWN;
7094
7095             // Check if this is a secondary process that should be incorporated into some
7096             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7097             // stuff above because profiling can currently happen only in the primary
7098             // instrumentation process.)
7099             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7100                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7101                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7102                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7103                         if (aInstr.mTargetProcesses.length == 0) {
7104                             // This is the wildcard mode, where every process brought up for
7105                             // the target instrumentation should be included.
7106                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7107                                 app.instr = aInstr;
7108                                 aInstr.mRunningProcesses.add(app);
7109                             }
7110                         } else {
7111                             for (String proc : aInstr.mTargetProcesses) {
7112                                 if (proc.equals(app.processName)) {
7113                                     app.instr = aInstr;
7114                                     aInstr.mRunningProcesses.add(app);
7115                                     break;
7116                                 }
7117                             }
7118                         }
7119                     }
7120                 }
7121             }
7122
7123             // If we were asked to attach an agent on startup, do so now, before we're binding
7124             // application code.
7125             if (preBindAgent != null) {
7126                 thread.attachAgent(preBindAgent);
7127             }
7128
7129             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7130             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7131             if (app.instr != null) {
7132                 thread.bindApplication(processName, appInfo, providers,
7133                         app.instr.mClass,
7134                         profilerInfo, app.instr.mArguments,
7135                         app.instr.mWatcher,
7136                         app.instr.mUiAutomationConnection, testMode,
7137                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7138                         isRestrictedBackupMode || !normalMode, app.persistent,
7139                         new Configuration(getGlobalConfiguration()), app.compat,
7140                         getCommonServicesLocked(app.isolated),
7141                         mCoreSettingsObserver.getCoreSettingsLocked(),
7142                         buildSerial);
7143             } else {
7144                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7145                         null, null, null, testMode,
7146                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7147                         isRestrictedBackupMode || !normalMode, app.persistent,
7148                         new Configuration(getGlobalConfiguration()), app.compat,
7149                         getCommonServicesLocked(app.isolated),
7150                         mCoreSettingsObserver.getCoreSettingsLocked(),
7151                         buildSerial);
7152             }
7153
7154             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7155             updateLruProcessLocked(app, false, null);
7156             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7157             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7158         } catch (Exception e) {
7159             // todo: Yikes!  What should we do?  For now we will try to
7160             // start another process, but that could easily get us in
7161             // an infinite loop of restarting processes...
7162             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7163
7164             app.resetPackageList(mProcessStats);
7165             app.unlinkDeathRecipient();
7166             startProcessLocked(app, "bind fail", processName);
7167             return false;
7168         }
7169
7170         // Remove this record from the list of starting applications.
7171         mPersistentStartingProcesses.remove(app);
7172         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7173                 "Attach application locked removing on hold: " + app);
7174         mProcessesOnHold.remove(app);
7175
7176         boolean badApp = false;
7177         boolean didSomething = false;
7178
7179         // See if the top visible activity is waiting to run in this process...
7180         if (normalMode) {
7181             try {
7182                 if (mStackSupervisor.attachApplicationLocked(app)) {
7183                     didSomething = true;
7184                 }
7185             } catch (Exception e) {
7186                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7187                 badApp = true;
7188             }
7189         }
7190
7191         // Find any services that should be running in this process...
7192         if (!badApp) {
7193             try {
7194                 didSomething |= mServices.attachApplicationLocked(app, processName);
7195                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7196             } catch (Exception e) {
7197                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7198                 badApp = true;
7199             }
7200         }
7201
7202         // Check if a next-broadcast receiver is in this process...
7203         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7204             try {
7205                 didSomething |= sendPendingBroadcastsLocked(app);
7206                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7207             } catch (Exception e) {
7208                 // If the app died trying to launch the receiver we declare it 'bad'
7209                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7210                 badApp = true;
7211             }
7212         }
7213
7214         // Check whether the next backup agent is in this process...
7215         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7216             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7217                     "New app is backup target, launching agent for " + app);
7218             notifyPackageUse(mBackupTarget.appInfo.packageName,
7219                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7220             try {
7221                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7222                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7223                         mBackupTarget.backupMode);
7224             } catch (Exception e) {
7225                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7226                 badApp = true;
7227             }
7228         }
7229
7230         if (badApp) {
7231             app.kill("error during init", true);
7232             handleAppDiedLocked(app, false, true);
7233             return false;
7234         }
7235
7236         if (!didSomething) {
7237             updateOomAdjLocked();
7238             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7239         }
7240
7241         return true;
7242     }
7243
7244     @Override
7245     public final void attachApplication(IApplicationThread thread) {
7246         synchronized (this) {
7247             int callingPid = Binder.getCallingPid();
7248             final long origId = Binder.clearCallingIdentity();
7249             attachApplicationLocked(thread, callingPid);
7250             Binder.restoreCallingIdentity(origId);
7251         }
7252     }
7253
7254     @Override
7255     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7256         final long origId = Binder.clearCallingIdentity();
7257         synchronized (this) {
7258             ActivityStack stack = ActivityRecord.getStackLocked(token);
7259             if (stack != null) {
7260                 ActivityRecord r =
7261                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7262                                 false /* processPausingActivities */, config);
7263                 if (stopProfiling) {
7264                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7265                         clearProfilerLocked();
7266                     }
7267                 }
7268             }
7269         }
7270         Binder.restoreCallingIdentity(origId);
7271     }
7272
7273     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7274         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7275                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7276     }
7277
7278     void enableScreenAfterBoot() {
7279         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7280                 SystemClock.uptimeMillis());
7281         mWindowManager.enableScreenAfterBoot();
7282
7283         synchronized (this) {
7284             updateEventDispatchingLocked();
7285         }
7286     }
7287
7288     @Override
7289     public void showBootMessage(final CharSequence msg, final boolean always) {
7290         if (Binder.getCallingUid() != myUid()) {
7291             throw new SecurityException();
7292         }
7293         mWindowManager.showBootMessage(msg, always);
7294     }
7295
7296     @Override
7297     public void keyguardGoingAway(int flags) {
7298         enforceNotIsolatedCaller("keyguardGoingAway");
7299         final long token = Binder.clearCallingIdentity();
7300         try {
7301             synchronized (this) {
7302                 mKeyguardController.keyguardGoingAway(flags);
7303             }
7304         } finally {
7305             Binder.restoreCallingIdentity(token);
7306         }
7307     }
7308
7309     /**
7310      * @return whther the keyguard is currently locked.
7311      */
7312     boolean isKeyguardLocked() {
7313         return mKeyguardController.isKeyguardLocked();
7314     }
7315
7316     final void finishBooting() {
7317         synchronized (this) {
7318             if (!mBootAnimationComplete) {
7319                 mCallFinishBooting = true;
7320                 return;
7321             }
7322             mCallFinishBooting = false;
7323         }
7324
7325         ArraySet<String> completedIsas = new ArraySet<String>();
7326         for (String abi : Build.SUPPORTED_ABIS) {
7327             zygoteProcess.establishZygoteConnectionForAbi(abi);
7328             final String instructionSet = VMRuntime.getInstructionSet(abi);
7329             if (!completedIsas.contains(instructionSet)) {
7330                 try {
7331                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7332                 } catch (InstallerException e) {
7333                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7334                             e.getMessage() +")");
7335                 }
7336                 completedIsas.add(instructionSet);
7337             }
7338         }
7339
7340         IntentFilter pkgFilter = new IntentFilter();
7341         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7342         pkgFilter.addDataScheme("package");
7343         mContext.registerReceiver(new BroadcastReceiver() {
7344             @Override
7345             public void onReceive(Context context, Intent intent) {
7346                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7347                 if (pkgs != null) {
7348                     for (String pkg : pkgs) {
7349                         synchronized (ActivityManagerService.this) {
7350                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7351                                     0, "query restart")) {
7352                                 setResultCode(Activity.RESULT_OK);
7353                                 return;
7354                             }
7355                         }
7356                     }
7357                 }
7358             }
7359         }, pkgFilter);
7360
7361         IntentFilter dumpheapFilter = new IntentFilter();
7362         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7363         mContext.registerReceiver(new BroadcastReceiver() {
7364             @Override
7365             public void onReceive(Context context, Intent intent) {
7366                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7367                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7368                 } else {
7369                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7370                 }
7371             }
7372         }, dumpheapFilter);
7373
7374         // Let system services know.
7375         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7376
7377         synchronized (this) {
7378             // Ensure that any processes we had put on hold are now started
7379             // up.
7380             final int NP = mProcessesOnHold.size();
7381             if (NP > 0) {
7382                 ArrayList<ProcessRecord> procs =
7383                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7384                 for (int ip=0; ip<NP; ip++) {
7385                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7386                             + procs.get(ip));
7387                     startProcessLocked(procs.get(ip), "on-hold", null);
7388                 }
7389             }
7390
7391             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7392                 // Start looking for apps that are abusing wake locks.
7393                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7394                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7395                 // Tell anyone interested that we are done booting!
7396                 SystemProperties.set("sys.boot_completed", "1");
7397
7398                 // And trigger dev.bootcomplete if we are not showing encryption progress
7399                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7400                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7401                     SystemProperties.set("dev.bootcomplete", "1");
7402                 }
7403                 mUserController.sendBootCompletedLocked(
7404                         new IIntentReceiver.Stub() {
7405                             @Override
7406                             public void performReceive(Intent intent, int resultCode,
7407                                     String data, Bundle extras, boolean ordered,
7408                                     boolean sticky, int sendingUser) {
7409                                 synchronized (ActivityManagerService.this) {
7410                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7411                                             true, false);
7412                                 }
7413                             }
7414                         });
7415                 scheduleStartProfilesLocked();
7416             }
7417         }
7418     }
7419
7420     @Override
7421     public void bootAnimationComplete() {
7422         final boolean callFinishBooting;
7423         synchronized (this) {
7424             callFinishBooting = mCallFinishBooting;
7425             mBootAnimationComplete = true;
7426         }
7427         if (callFinishBooting) {
7428             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7429             finishBooting();
7430             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7431         }
7432     }
7433
7434     final void ensureBootCompleted() {
7435         boolean booting;
7436         boolean enableScreen;
7437         synchronized (this) {
7438             booting = mBooting;
7439             mBooting = false;
7440             enableScreen = !mBooted;
7441             mBooted = true;
7442         }
7443
7444         if (booting) {
7445             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7446             finishBooting();
7447             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7448         }
7449
7450         if (enableScreen) {
7451             enableScreenAfterBoot();
7452         }
7453     }
7454
7455     @Override
7456     public final void activityResumed(IBinder token) {
7457         final long origId = Binder.clearCallingIdentity();
7458         synchronized(this) {
7459             ActivityRecord.activityResumedLocked(token);
7460             mWindowManager.notifyAppResumedFinished(token);
7461         }
7462         Binder.restoreCallingIdentity(origId);
7463     }
7464
7465     @Override
7466     public final void activityPaused(IBinder token) {
7467         final long origId = Binder.clearCallingIdentity();
7468         synchronized(this) {
7469             ActivityStack stack = ActivityRecord.getStackLocked(token);
7470             if (stack != null) {
7471                 stack.activityPausedLocked(token, false);
7472             }
7473         }
7474         Binder.restoreCallingIdentity(origId);
7475     }
7476
7477     @Override
7478     public final void activityStopped(IBinder token, Bundle icicle,
7479             PersistableBundle persistentState, CharSequence description) {
7480         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7481
7482         // Refuse possible leaked file descriptors
7483         if (icicle != null && icicle.hasFileDescriptors()) {
7484             throw new IllegalArgumentException("File descriptors passed in Bundle");
7485         }
7486
7487         final long origId = Binder.clearCallingIdentity();
7488
7489         synchronized (this) {
7490             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7491             if (r != null) {
7492                 r.activityStoppedLocked(icicle, persistentState, description);
7493             }
7494         }
7495
7496         trimApplications();
7497
7498         Binder.restoreCallingIdentity(origId);
7499     }
7500
7501     @Override
7502     public final void activityDestroyed(IBinder token) {
7503         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7504         synchronized (this) {
7505             ActivityStack stack = ActivityRecord.getStackLocked(token);
7506             if (stack != null) {
7507                 stack.activityDestroyedLocked(token, "activityDestroyed");
7508             }
7509         }
7510     }
7511
7512     @Override
7513     public final void activityRelaunched(IBinder token) {
7514         final long origId = Binder.clearCallingIdentity();
7515         synchronized (this) {
7516             mStackSupervisor.activityRelaunchedLocked(token);
7517         }
7518         Binder.restoreCallingIdentity(origId);
7519     }
7520
7521     @Override
7522     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7523             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7524         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7525                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7526         synchronized (this) {
7527             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7528             if (record == null) {
7529                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7530                         + "found for: " + token);
7531             }
7532             record.setSizeConfigurations(horizontalSizeConfiguration,
7533                     verticalSizeConfigurations, smallestSizeConfigurations);
7534         }
7535     }
7536
7537     @Override
7538     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7539         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7540     }
7541
7542     @Override
7543     public final void notifyEnterAnimationComplete(IBinder token) {
7544         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7545     }
7546
7547     @Override
7548     public String getCallingPackage(IBinder token) {
7549         synchronized (this) {
7550             ActivityRecord r = getCallingRecordLocked(token);
7551             return r != null ? r.info.packageName : null;
7552         }
7553     }
7554
7555     @Override
7556     public ComponentName getCallingActivity(IBinder token) {
7557         synchronized (this) {
7558             ActivityRecord r = getCallingRecordLocked(token);
7559             return r != null ? r.intent.getComponent() : null;
7560         }
7561     }
7562
7563     private ActivityRecord getCallingRecordLocked(IBinder token) {
7564         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7565         if (r == null) {
7566             return null;
7567         }
7568         return r.resultTo;
7569     }
7570
7571     @Override
7572     public ComponentName getActivityClassForToken(IBinder token) {
7573         synchronized(this) {
7574             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7575             if (r == null) {
7576                 return null;
7577             }
7578             return r.intent.getComponent();
7579         }
7580     }
7581
7582     @Override
7583     public String getPackageForToken(IBinder token) {
7584         synchronized(this) {
7585             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7586             if (r == null) {
7587                 return null;
7588             }
7589             return r.packageName;
7590         }
7591     }
7592
7593     @Override
7594     public boolean isRootVoiceInteraction(IBinder token) {
7595         synchronized(this) {
7596             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7597             if (r == null) {
7598                 return false;
7599             }
7600             return r.rootVoiceInteraction;
7601         }
7602     }
7603
7604     @Override
7605     public IIntentSender getIntentSender(int type,
7606             String packageName, IBinder token, String resultWho,
7607             int requestCode, Intent[] intents, String[] resolvedTypes,
7608             int flags, Bundle bOptions, int userId) {
7609         enforceNotIsolatedCaller("getIntentSender");
7610         // Refuse possible leaked file descriptors
7611         if (intents != null) {
7612             if (intents.length < 1) {
7613                 throw new IllegalArgumentException("Intents array length must be >= 1");
7614             }
7615             for (int i=0; i<intents.length; i++) {
7616                 Intent intent = intents[i];
7617                 if (intent != null) {
7618                     if (intent.hasFileDescriptors()) {
7619                         throw new IllegalArgumentException("File descriptors passed in Intent");
7620                     }
7621                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7622                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7623                         throw new IllegalArgumentException(
7624                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7625                     }
7626                     intents[i] = new Intent(intent);
7627                 }
7628             }
7629             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7630                 throw new IllegalArgumentException(
7631                         "Intent array length does not match resolvedTypes length");
7632             }
7633         }
7634         if (bOptions != null) {
7635             if (bOptions.hasFileDescriptors()) {
7636                 throw new IllegalArgumentException("File descriptors passed in options");
7637             }
7638         }
7639
7640         synchronized(this) {
7641             int callingUid = Binder.getCallingUid();
7642             int origUserId = userId;
7643             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7644                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7645                     ALLOW_NON_FULL, "getIntentSender", null);
7646             if (origUserId == UserHandle.USER_CURRENT) {
7647                 // We don't want to evaluate this until the pending intent is
7648                 // actually executed.  However, we do want to always do the
7649                 // security checking for it above.
7650                 userId = UserHandle.USER_CURRENT;
7651             }
7652             try {
7653                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7654                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7655                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7656                     if (!UserHandle.isSameApp(callingUid, uid)) {
7657                         String msg = "Permission Denial: getIntentSender() from pid="
7658                             + Binder.getCallingPid()
7659                             + ", uid=" + Binder.getCallingUid()
7660                             + ", (need uid=" + uid + ")"
7661                             + " is not allowed to send as package " + packageName;
7662                         Slog.w(TAG, msg);
7663                         throw new SecurityException(msg);
7664                     }
7665                 }
7666
7667                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7668                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7669
7670             } catch (RemoteException e) {
7671                 throw new SecurityException(e);
7672             }
7673         }
7674     }
7675
7676     IIntentSender getIntentSenderLocked(int type, String packageName,
7677             int callingUid, int userId, IBinder token, String resultWho,
7678             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7679             Bundle bOptions) {
7680         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7681         ActivityRecord activity = null;
7682         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7683             activity = ActivityRecord.isInStackLocked(token);
7684             if (activity == null) {
7685                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7686                 return null;
7687             }
7688             if (activity.finishing) {
7689                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7690                 return null;
7691             }
7692         }
7693
7694         // We're going to be splicing together extras before sending, so we're
7695         // okay poking into any contained extras.
7696         if (intents != null) {
7697             for (int i = 0; i < intents.length; i++) {
7698                 intents[i].setDefusable(true);
7699             }
7700         }
7701         Bundle.setDefusable(bOptions, true);
7702
7703         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7704         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7705         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7706         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7707                 |PendingIntent.FLAG_UPDATE_CURRENT);
7708
7709         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7710                 type, packageName, activity, resultWho,
7711                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7712         WeakReference<PendingIntentRecord> ref;
7713         ref = mIntentSenderRecords.get(key);
7714         PendingIntentRecord rec = ref != null ? ref.get() : null;
7715         if (rec != null) {
7716             if (!cancelCurrent) {
7717                 if (updateCurrent) {
7718                     if (rec.key.requestIntent != null) {
7719                         rec.key.requestIntent.replaceExtras(intents != null ?
7720                                 intents[intents.length - 1] : null);
7721                     }
7722                     if (intents != null) {
7723                         intents[intents.length-1] = rec.key.requestIntent;
7724                         rec.key.allIntents = intents;
7725                         rec.key.allResolvedTypes = resolvedTypes;
7726                     } else {
7727                         rec.key.allIntents = null;
7728                         rec.key.allResolvedTypes = null;
7729                     }
7730                 }
7731                 return rec;
7732             }
7733             makeIntentSenderCanceledLocked(rec);
7734             mIntentSenderRecords.remove(key);
7735         }
7736         if (noCreate) {
7737             return rec;
7738         }
7739         rec = new PendingIntentRecord(this, key, callingUid);
7740         mIntentSenderRecords.put(key, rec.ref);
7741         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7742             if (activity.pendingResults == null) {
7743                 activity.pendingResults
7744                         = new HashSet<WeakReference<PendingIntentRecord>>();
7745             }
7746             activity.pendingResults.add(rec.ref);
7747         }
7748         return rec;
7749     }
7750
7751     @Override
7752     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7753             Intent intent, String resolvedType,
7754             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7755         if (target instanceof PendingIntentRecord) {
7756             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7757                     whitelistToken, finishedReceiver, requiredPermission, options);
7758         } else {
7759             if (intent == null) {
7760                 // Weird case: someone has given us their own custom IIntentSender, and now
7761                 // they have someone else trying to send to it but of course this isn't
7762                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7763                 // supplying an Intent... but we never want to dispatch a null Intent to
7764                 // a receiver, so um...  let's make something up.
7765                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7766                 intent = new Intent(Intent.ACTION_MAIN);
7767             }
7768             try {
7769                 target.send(code, intent, resolvedType, whitelistToken, null,
7770                         requiredPermission, options);
7771             } catch (RemoteException e) {
7772             }
7773             // Platform code can rely on getting a result back when the send is done, but if
7774             // this intent sender is from outside of the system we can't rely on it doing that.
7775             // So instead we don't give it the result receiver, and instead just directly
7776             // report the finish immediately.
7777             if (finishedReceiver != null) {
7778                 try {
7779                     finishedReceiver.performReceive(intent, 0,
7780                             null, null, false, false, UserHandle.getCallingUserId());
7781                 } catch (RemoteException e) {
7782                 }
7783             }
7784             return 0;
7785         }
7786     }
7787
7788     @Override
7789     public void cancelIntentSender(IIntentSender sender) {
7790         if (!(sender instanceof PendingIntentRecord)) {
7791             return;
7792         }
7793         synchronized(this) {
7794             PendingIntentRecord rec = (PendingIntentRecord)sender;
7795             try {
7796                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7797                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7798                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7799                     String msg = "Permission Denial: cancelIntentSender() from pid="
7800                         + Binder.getCallingPid()
7801                         + ", uid=" + Binder.getCallingUid()
7802                         + " is not allowed to cancel package "
7803                         + rec.key.packageName;
7804                     Slog.w(TAG, msg);
7805                     throw new SecurityException(msg);
7806                 }
7807             } catch (RemoteException e) {
7808                 throw new SecurityException(e);
7809             }
7810             cancelIntentSenderLocked(rec, true);
7811         }
7812     }
7813
7814     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7815         makeIntentSenderCanceledLocked(rec);
7816         mIntentSenderRecords.remove(rec.key);
7817         if (cleanActivity && rec.key.activity != null) {
7818             rec.key.activity.pendingResults.remove(rec.ref);
7819         }
7820     }
7821
7822     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7823         rec.canceled = true;
7824         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7825         if (callbacks != null) {
7826             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7827         }
7828     }
7829
7830     @Override
7831     public String getPackageForIntentSender(IIntentSender pendingResult) {
7832         if (!(pendingResult instanceof PendingIntentRecord)) {
7833             return null;
7834         }
7835         try {
7836             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7837             return res.key.packageName;
7838         } catch (ClassCastException e) {
7839         }
7840         return null;
7841     }
7842
7843     @Override
7844     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7845         if (!(sender instanceof PendingIntentRecord)) {
7846             return;
7847         }
7848         synchronized(this) {
7849             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7850         }
7851     }
7852
7853     @Override
7854     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7855             IResultReceiver receiver) {
7856         if (!(sender instanceof PendingIntentRecord)) {
7857             return;
7858         }
7859         synchronized(this) {
7860             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7861         }
7862     }
7863
7864     @Override
7865     public int getUidForIntentSender(IIntentSender sender) {
7866         if (sender instanceof PendingIntentRecord) {
7867             try {
7868                 PendingIntentRecord res = (PendingIntentRecord)sender;
7869                 return res.uid;
7870             } catch (ClassCastException e) {
7871             }
7872         }
7873         return -1;
7874     }
7875
7876     @Override
7877     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7878         if (!(pendingResult instanceof PendingIntentRecord)) {
7879             return false;
7880         }
7881         try {
7882             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7883             if (res.key.allIntents == null) {
7884                 return false;
7885             }
7886             for (int i=0; i<res.key.allIntents.length; i++) {
7887                 Intent intent = res.key.allIntents[i];
7888                 if (intent.getPackage() != null && intent.getComponent() != null) {
7889                     return false;
7890                 }
7891             }
7892             return true;
7893         } catch (ClassCastException e) {
7894         }
7895         return false;
7896     }
7897
7898     @Override
7899     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7900         if (!(pendingResult instanceof PendingIntentRecord)) {
7901             return false;
7902         }
7903         try {
7904             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7905             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7906                 return true;
7907             }
7908             return false;
7909         } catch (ClassCastException e) {
7910         }
7911         return false;
7912     }
7913
7914     @Override
7915     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7916         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7917                 "getIntentForIntentSender()");
7918         if (!(pendingResult instanceof PendingIntentRecord)) {
7919             return null;
7920         }
7921         try {
7922             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7923             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7924         } catch (ClassCastException e) {
7925         }
7926         return null;
7927     }
7928
7929     @Override
7930     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7931         if (!(pendingResult instanceof PendingIntentRecord)) {
7932             return null;
7933         }
7934         try {
7935             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7936             synchronized (this) {
7937                 return getTagForIntentSenderLocked(res, prefix);
7938             }
7939         } catch (ClassCastException e) {
7940         }
7941         return null;
7942     }
7943
7944     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7945         final Intent intent = res.key.requestIntent;
7946         if (intent != null) {
7947             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7948                     || res.lastTagPrefix.equals(prefix))) {
7949                 return res.lastTag;
7950             }
7951             res.lastTagPrefix = prefix;
7952             final StringBuilder sb = new StringBuilder(128);
7953             if (prefix != null) {
7954                 sb.append(prefix);
7955             }
7956             if (intent.getAction() != null) {
7957                 sb.append(intent.getAction());
7958             } else if (intent.getComponent() != null) {
7959                 intent.getComponent().appendShortString(sb);
7960             } else {
7961                 sb.append("?");
7962             }
7963             return res.lastTag = sb.toString();
7964         }
7965         return null;
7966     }
7967
7968     @Override
7969     public void setProcessLimit(int max) {
7970         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7971                 "setProcessLimit()");
7972         synchronized (this) {
7973             mConstants.setOverrideMaxCachedProcesses(max);
7974         }
7975         trimApplications();
7976     }
7977
7978     @Override
7979     public int getProcessLimit() {
7980         synchronized (this) {
7981             return mConstants.getOverrideMaxCachedProcesses();
7982         }
7983     }
7984
7985     void importanceTokenDied(ImportanceToken token) {
7986         synchronized (ActivityManagerService.this) {
7987             synchronized (mPidsSelfLocked) {
7988                 ImportanceToken cur
7989                     = mImportantProcesses.get(token.pid);
7990                 if (cur != token) {
7991                     return;
7992                 }
7993                 mImportantProcesses.remove(token.pid);
7994                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7995                 if (pr == null) {
7996                     return;
7997                 }
7998                 pr.forcingToImportant = null;
7999                 updateProcessForegroundLocked(pr, false, false);
8000             }
8001             updateOomAdjLocked();
8002         }
8003     }
8004
8005     @Override
8006     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
8007         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
8008                 "setProcessImportant()");
8009         synchronized(this) {
8010             boolean changed = false;
8011
8012             synchronized (mPidsSelfLocked) {
8013                 ProcessRecord pr = mPidsSelfLocked.get(pid);
8014                 if (pr == null && isForeground) {
8015                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
8016                     return;
8017                 }
8018                 ImportanceToken oldToken = mImportantProcesses.get(pid);
8019                 if (oldToken != null) {
8020                     oldToken.token.unlinkToDeath(oldToken, 0);
8021                     mImportantProcesses.remove(pid);
8022                     if (pr != null) {
8023                         pr.forcingToImportant = null;
8024                     }
8025                     changed = true;
8026                 }
8027                 if (isForeground && token != null) {
8028                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8029                         @Override
8030                         public void binderDied() {
8031                             importanceTokenDied(this);
8032                         }
8033                     };
8034                     try {
8035                         token.linkToDeath(newToken, 0);
8036                         mImportantProcesses.put(pid, newToken);
8037                         pr.forcingToImportant = newToken;
8038                         changed = true;
8039                     } catch (RemoteException e) {
8040                         // If the process died while doing this, we will later
8041                         // do the cleanup with the process death link.
8042                     }
8043                 }
8044             }
8045
8046             if (changed) {
8047                 updateOomAdjLocked();
8048             }
8049         }
8050     }
8051
8052     @Override
8053     public boolean isAppForeground(int uid) throws RemoteException {
8054         synchronized (this) {
8055             UidRecord uidRec = mActiveUids.get(uid);
8056             if (uidRec == null || uidRec.idle) {
8057                 return false;
8058             }
8059             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8060         }
8061     }
8062
8063     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8064     // be guarded by permission checking.
8065     int getUidState(int uid) {
8066         synchronized (this) {
8067             return getUidStateLocked(uid);
8068         }
8069     }
8070
8071     int getUidStateLocked(int uid) {
8072         UidRecord uidRec = mActiveUids.get(uid);
8073         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8074     }
8075
8076     @Override
8077     public boolean isInMultiWindowMode(IBinder token) {
8078         final long origId = Binder.clearCallingIdentity();
8079         try {
8080             synchronized(this) {
8081                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8082                 if (r == null) {
8083                     return false;
8084                 }
8085                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8086                 return !r.getTask().mFullscreen;
8087             }
8088         } finally {
8089             Binder.restoreCallingIdentity(origId);
8090         }
8091     }
8092
8093     @Override
8094     public boolean isInPictureInPictureMode(IBinder token) {
8095         final long origId = Binder.clearCallingIdentity();
8096         try {
8097             synchronized(this) {
8098                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8099             }
8100         } finally {
8101             Binder.restoreCallingIdentity(origId);
8102         }
8103     }
8104
8105     private boolean isInPictureInPictureMode(ActivityRecord r) {
8106         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8107                 r.getStack().isInStackLocked(r) == null) {
8108             return false;
8109         }
8110
8111         // If we are animating to fullscreen then we have already dispatched the PIP mode
8112         // changed, so we should reflect that check here as well.
8113         final PinnedActivityStack stack = r.getStack();
8114         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8115         return !windowController.isAnimatingBoundsToFullscreen();
8116     }
8117
8118     @Override
8119     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8120         final long origId = Binder.clearCallingIdentity();
8121         try {
8122             synchronized(this) {
8123                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8124                         "enterPictureInPictureMode", token, params);
8125
8126                 // If the activity is already in picture in picture mode, then just return early
8127                 if (isInPictureInPictureMode(r)) {
8128                     return true;
8129                 }
8130
8131                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8132                 // point, if it is
8133                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8134                         false /* beforeStopping */)) {
8135                     return false;
8136                 }
8137
8138                 final Runnable enterPipRunnable = () -> {
8139                     // Only update the saved args from the args that are set
8140                     r.pictureInPictureArgs.copyOnlySet(params);
8141                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8142                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8143                     // Adjust the source bounds by the insets for the transition down
8144                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8145                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8146                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8147                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8148                     stack.setPictureInPictureAspectRatio(aspectRatio);
8149                     stack.setPictureInPictureActions(actions);
8150
8151                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8152                             r.supportsEnterPipOnTaskSwitch);
8153                     logPictureInPictureArgs(params);
8154                 };
8155
8156                 if (isKeyguardLocked()) {
8157                     // If the keyguard is showing or occluded, then try and dismiss it before
8158                     // entering picture-in-picture (this will prompt the user to authenticate if the
8159                     // device is currently locked).
8160                     try {
8161                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8162                             @Override
8163                             public void onDismissError() throws RemoteException {
8164                                 // Do nothing
8165                             }
8166
8167                             @Override
8168                             public void onDismissSucceeded() throws RemoteException {
8169                                 mHandler.post(enterPipRunnable);
8170                             }
8171
8172                             @Override
8173                             public void onDismissCancelled() throws RemoteException {
8174                                 // Do nothing
8175                             }
8176                         });
8177                     } catch (RemoteException e) {
8178                         // Local call
8179                     }
8180                 } else {
8181                     // Enter picture in picture immediately otherwise
8182                     enterPipRunnable.run();
8183                 }
8184                 return true;
8185             }
8186         } finally {
8187             Binder.restoreCallingIdentity(origId);
8188         }
8189     }
8190
8191     @Override
8192     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8193         final long origId = Binder.clearCallingIdentity();
8194         try {
8195             synchronized(this) {
8196                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8197                         "setPictureInPictureParams", token, params);
8198
8199                 // Only update the saved args from the args that are set
8200                 r.pictureInPictureArgs.copyOnlySet(params);
8201                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8202                     // If the activity is already in picture-in-picture, update the pinned stack now
8203                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8204                     // be used the next time the activity enters PiP
8205                     final PinnedActivityStack stack = r.getStack();
8206                     if (!stack.isAnimatingBoundsToFullscreen()) {
8207                         stack.setPictureInPictureAspectRatio(
8208                                 r.pictureInPictureArgs.getAspectRatio());
8209                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8210                     }
8211                 }
8212                 logPictureInPictureArgs(params);
8213             }
8214         } finally {
8215             Binder.restoreCallingIdentity(origId);
8216         }
8217     }
8218
8219     @Override
8220     public int getMaxNumPictureInPictureActions(IBinder token) {
8221         // Currently, this is a static constant, but later, we may change this to be dependent on
8222         // the context of the activity
8223         return 3;
8224     }
8225
8226     private void logPictureInPictureArgs(PictureInPictureParams params) {
8227         if (params.hasSetActions()) {
8228             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8229                     params.getActions().size());
8230         }
8231         if (params.hasSetAspectRatio()) {
8232             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8233             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8234             MetricsLogger.action(lm);
8235         }
8236     }
8237
8238     /**
8239      * Checks the state of the system and the activity associated with the given {@param token} to
8240      * verify that picture-in-picture is supported for that activity.
8241      *
8242      * @return the activity record for the given {@param token} if all the checks pass.
8243      */
8244     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8245             IBinder token, PictureInPictureParams params) {
8246         if (!mSupportsPictureInPicture) {
8247             throw new IllegalStateException(caller
8248                     + ": Device doesn't support picture-in-picture mode.");
8249         }
8250
8251         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8252         if (r == null) {
8253             throw new IllegalStateException(caller
8254                     + ": Can't find activity for token=" + token);
8255         }
8256
8257         if (!r.supportsPictureInPicture()) {
8258             throw new IllegalStateException(caller
8259                     + ": Current activity does not support picture-in-picture.");
8260         }
8261
8262         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8263             throw new IllegalStateException(caller
8264                     + ": Activities on the home, assistant, or recents stack not supported");
8265         }
8266
8267         if (params.hasSetAspectRatio()
8268                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8269                         params.getAspectRatio())) {
8270             final float minAspectRatio = mContext.getResources().getFloat(
8271                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8272             final float maxAspectRatio = mContext.getResources().getFloat(
8273                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8274             throw new IllegalArgumentException(String.format(caller
8275                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8276                             minAspectRatio, maxAspectRatio));
8277         }
8278
8279         // Truncate the number of actions if necessary
8280         params.truncateActions(getMaxNumPictureInPictureActions(token));
8281
8282         return r;
8283     }
8284
8285     // =========================================================
8286     // PROCESS INFO
8287     // =========================================================
8288
8289     static class ProcessInfoService extends IProcessInfoService.Stub {
8290         final ActivityManagerService mActivityManagerService;
8291         ProcessInfoService(ActivityManagerService activityManagerService) {
8292             mActivityManagerService = activityManagerService;
8293         }
8294
8295         @Override
8296         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8297             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8298                     /*in*/ pids, /*out*/ states, null);
8299         }
8300
8301         @Override
8302         public void getProcessStatesAndOomScoresFromPids(
8303                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8304             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8305                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8306         }
8307     }
8308
8309     /**
8310      * For each PID in the given input array, write the current process state
8311      * for that process into the states array, or -1 to indicate that no
8312      * process with the given PID exists. If scores array is provided, write
8313      * the oom score for the process into the scores array, with INVALID_ADJ
8314      * indicating the PID doesn't exist.
8315      */
8316     public void getProcessStatesAndOomScoresForPIDs(
8317             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8318         if (scores != null) {
8319             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8320                     "getProcessStatesAndOomScoresForPIDs()");
8321         }
8322
8323         if (pids == null) {
8324             throw new NullPointerException("pids");
8325         } else if (states == null) {
8326             throw new NullPointerException("states");
8327         } else if (pids.length != states.length) {
8328             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8329         } else if (scores != null && pids.length != scores.length) {
8330             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8331         }
8332
8333         synchronized (mPidsSelfLocked) {
8334             for (int i = 0; i < pids.length; i++) {
8335                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8336                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8337                         pr.curProcState;
8338                 if (scores != null) {
8339                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8340                 }
8341             }
8342         }
8343     }
8344
8345     // =========================================================
8346     // PERMISSIONS
8347     // =========================================================
8348
8349     static class PermissionController extends IPermissionController.Stub {
8350         ActivityManagerService mActivityManagerService;
8351         PermissionController(ActivityManagerService activityManagerService) {
8352             mActivityManagerService = activityManagerService;
8353         }
8354
8355         @Override
8356         public boolean checkPermission(String permission, int pid, int uid) {
8357             return mActivityManagerService.checkPermission(permission, pid,
8358                     uid) == PackageManager.PERMISSION_GRANTED;
8359         }
8360
8361         @Override
8362         public String[] getPackagesForUid(int uid) {
8363             return mActivityManagerService.mContext.getPackageManager()
8364                     .getPackagesForUid(uid);
8365         }
8366
8367         @Override
8368         public boolean isRuntimePermission(String permission) {
8369             try {
8370                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8371                         .getPermissionInfo(permission, 0);
8372                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8373                         == PermissionInfo.PROTECTION_DANGEROUS;
8374             } catch (NameNotFoundException nnfe) {
8375                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8376             }
8377             return false;
8378         }
8379     }
8380
8381     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8382         @Override
8383         public int checkComponentPermission(String permission, int pid, int uid,
8384                 int owningUid, boolean exported) {
8385             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8386                     owningUid, exported);
8387         }
8388
8389         @Override
8390         public Object getAMSLock() {
8391             return ActivityManagerService.this;
8392         }
8393     }
8394
8395     /**
8396      * This can be called with or without the global lock held.
8397      */
8398     int checkComponentPermission(String permission, int pid, int uid,
8399             int owningUid, boolean exported) {
8400         if (pid == MY_PID) {
8401             return PackageManager.PERMISSION_GRANTED;
8402         }
8403         return ActivityManager.checkComponentPermission(permission, uid,
8404                 owningUid, exported);
8405     }
8406
8407     /**
8408      * As the only public entry point for permissions checking, this method
8409      * can enforce the semantic that requesting a check on a null global
8410      * permission is automatically denied.  (Internally a null permission
8411      * string is used when calling {@link #checkComponentPermission} in cases
8412      * when only uid-based security is needed.)
8413      *
8414      * This can be called with or without the global lock held.
8415      */
8416     @Override
8417     public int checkPermission(String permission, int pid, int uid) {
8418         if (permission == null) {
8419             return PackageManager.PERMISSION_DENIED;
8420         }
8421         return checkComponentPermission(permission, pid, uid, -1, true);
8422     }
8423
8424     @Override
8425     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8426         if (permission == null) {
8427             return PackageManager.PERMISSION_DENIED;
8428         }
8429
8430         // We might be performing an operation on behalf of an indirect binder
8431         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8432         // client identity accordingly before proceeding.
8433         Identity tlsIdentity = sCallerIdentity.get();
8434         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8435             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8436                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8437             uid = tlsIdentity.uid;
8438             pid = tlsIdentity.pid;
8439         }
8440
8441         return checkComponentPermission(permission, pid, uid, -1, true);
8442     }
8443
8444     /**
8445      * Binder IPC calls go through the public entry point.
8446      * This can be called with or without the global lock held.
8447      */
8448     int checkCallingPermission(String permission) {
8449         return checkPermission(permission,
8450                 Binder.getCallingPid(),
8451                 UserHandle.getAppId(Binder.getCallingUid()));
8452     }
8453
8454     /**
8455      * This can be called with or without the global lock held.
8456      */
8457     void enforceCallingPermission(String permission, String func) {
8458         if (checkCallingPermission(permission)
8459                 == PackageManager.PERMISSION_GRANTED) {
8460             return;
8461         }
8462
8463         String msg = "Permission Denial: " + func + " from pid="
8464                 + Binder.getCallingPid()
8465                 + ", uid=" + Binder.getCallingUid()
8466                 + " requires " + permission;
8467         Slog.w(TAG, msg);
8468         throw new SecurityException(msg);
8469     }
8470
8471     /**
8472      * Determine if UID is holding permissions required to access {@link Uri} in
8473      * the given {@link ProviderInfo}. Final permission checking is always done
8474      * in {@link ContentProvider}.
8475      */
8476     private final boolean checkHoldingPermissionsLocked(
8477             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8478         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8479                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8480         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8481             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8482                     != PERMISSION_GRANTED) {
8483                 return false;
8484             }
8485         }
8486         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8487     }
8488
8489     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8490             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8491         if (pi.applicationInfo.uid == uid) {
8492             return true;
8493         } else if (!pi.exported) {
8494             return false;
8495         }
8496
8497         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8498         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8499         try {
8500             // check if target holds top-level <provider> permissions
8501             if (!readMet && pi.readPermission != null && considerUidPermissions
8502                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8503                 readMet = true;
8504             }
8505             if (!writeMet && pi.writePermission != null && considerUidPermissions
8506                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8507                 writeMet = true;
8508             }
8509
8510             // track if unprotected read/write is allowed; any denied
8511             // <path-permission> below removes this ability
8512             boolean allowDefaultRead = pi.readPermission == null;
8513             boolean allowDefaultWrite = pi.writePermission == null;
8514
8515             // check if target holds any <path-permission> that match uri
8516             final PathPermission[] pps = pi.pathPermissions;
8517             if (pps != null) {
8518                 final String path = grantUri.uri.getPath();
8519                 int i = pps.length;
8520                 while (i > 0 && (!readMet || !writeMet)) {
8521                     i--;
8522                     PathPermission pp = pps[i];
8523                     if (pp.match(path)) {
8524                         if (!readMet) {
8525                             final String pprperm = pp.getReadPermission();
8526                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8527                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8528                                     + ": match=" + pp.match(path)
8529                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8530                             if (pprperm != null) {
8531                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8532                                         == PERMISSION_GRANTED) {
8533                                     readMet = true;
8534                                 } else {
8535                                     allowDefaultRead = false;
8536                                 }
8537                             }
8538                         }
8539                         if (!writeMet) {
8540                             final String ppwperm = pp.getWritePermission();
8541                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8542                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8543                                     + ": match=" + pp.match(path)
8544                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8545                             if (ppwperm != null) {
8546                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8547                                         == PERMISSION_GRANTED) {
8548                                     writeMet = true;
8549                                 } else {
8550                                     allowDefaultWrite = false;
8551                                 }
8552                             }
8553                         }
8554                     }
8555                 }
8556             }
8557
8558             // grant unprotected <provider> read/write, if not blocked by
8559             // <path-permission> above
8560             if (allowDefaultRead) readMet = true;
8561             if (allowDefaultWrite) writeMet = true;
8562
8563         } catch (RemoteException e) {
8564             return false;
8565         }
8566
8567         return readMet && writeMet;
8568     }
8569
8570     public boolean isAppStartModeDisabled(int uid, String packageName) {
8571         synchronized (this) {
8572             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8573                     == ActivityManager.APP_START_MODE_DISABLED;
8574         }
8575     }
8576
8577     // Unified app-op and target sdk check
8578     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8579         // Apps that target O+ are always subject to background check
8580         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8581             if (DEBUG_BACKGROUND_CHECK) {
8582                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8583             }
8584             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8585         }
8586         // ...and legacy apps get an AppOp check
8587         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8588                 uid, packageName);
8589         if (DEBUG_BACKGROUND_CHECK) {
8590             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8591         }
8592         switch (appop) {
8593             case AppOpsManager.MODE_ALLOWED:
8594                 return ActivityManager.APP_START_MODE_NORMAL;
8595             case AppOpsManager.MODE_IGNORED:
8596                 return ActivityManager.APP_START_MODE_DELAYED;
8597             default:
8598                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8599         }
8600     }
8601
8602     // Service launch is available to apps with run-in-background exemptions but
8603     // some other background operations are not.  If we're doing a check
8604     // of service-launch policy, allow those callers to proceed unrestricted.
8605     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8606         // Persistent app?
8607         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8608             if (DEBUG_BACKGROUND_CHECK) {
8609                 Slog.i(TAG, "App " + uid + "/" + packageName
8610                         + " is persistent; not restricted in background");
8611             }
8612             return ActivityManager.APP_START_MODE_NORMAL;
8613         }
8614
8615         // Non-persistent but background whitelisted?
8616         if (uidOnBackgroundWhitelist(uid)) {
8617             if (DEBUG_BACKGROUND_CHECK) {
8618                 Slog.i(TAG, "App " + uid + "/" + packageName
8619                         + " on background whitelist; not restricted in background");
8620             }
8621             return ActivityManager.APP_START_MODE_NORMAL;
8622         }
8623
8624         // Is this app on the battery whitelist?
8625         if (isOnDeviceIdleWhitelistLocked(uid)) {
8626             if (DEBUG_BACKGROUND_CHECK) {
8627                 Slog.i(TAG, "App " + uid + "/" + packageName
8628                         + " on idle whitelist; not restricted in background");
8629             }
8630             return ActivityManager.APP_START_MODE_NORMAL;
8631         }
8632
8633         // None of the service-policy criteria apply, so we apply the common criteria
8634         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8635     }
8636
8637     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8638             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8639         UidRecord uidRec = mActiveUids.get(uid);
8640         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8641                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8642                 + (uidRec != null ? uidRec.idle : false));
8643         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8644             boolean ephemeral;
8645             if (uidRec == null) {
8646                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8647                         UserHandle.getUserId(uid), packageName);
8648             } else {
8649                 ephemeral = uidRec.ephemeral;
8650             }
8651
8652             if (ephemeral) {
8653                 // We are hard-core about ephemeral apps not running in the background.
8654                 return ActivityManager.APP_START_MODE_DISABLED;
8655             } else {
8656                 if (disabledOnly) {
8657                     // The caller is only interested in whether app starts are completely
8658                     // disabled for the given package (that is, it is an instant app).  So
8659                     // we don't need to go further, which is all just seeing if we should
8660                     // apply a "delayed" mode for a regular app.
8661                     return ActivityManager.APP_START_MODE_NORMAL;
8662                 }
8663                 final int startMode = (alwaysRestrict)
8664                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8665                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8666                                 packageTargetSdk);
8667                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8668                         + " pkg=" + packageName + " startMode=" + startMode
8669                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8670                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8671                     // This is an old app that has been forced into a "compatible as possible"
8672                     // mode of background check.  To increase compatibility, we will allow other
8673                     // foreground apps to cause its services to start.
8674                     if (callingPid >= 0) {
8675                         ProcessRecord proc;
8676                         synchronized (mPidsSelfLocked) {
8677                             proc = mPidsSelfLocked.get(callingPid);
8678                         }
8679                         if (proc != null &&
8680                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8681                             // Whoever is instigating this is in the foreground, so we will allow it
8682                             // to go through.
8683                             return ActivityManager.APP_START_MODE_NORMAL;
8684                         }
8685                     }
8686                 }
8687                 return startMode;
8688             }
8689         }
8690         return ActivityManager.APP_START_MODE_NORMAL;
8691     }
8692
8693     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8694         final int appId = UserHandle.getAppId(uid);
8695         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8696                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8697                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8698     }
8699
8700     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8701         ProviderInfo pi = null;
8702         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8703         if (cpr != null) {
8704             pi = cpr.info;
8705         } else {
8706             try {
8707                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8708                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8709                         userHandle);
8710             } catch (RemoteException ex) {
8711             }
8712         }
8713         return pi;
8714     }
8715
8716     void grantEphemeralAccessLocked(int userId, Intent intent,
8717             int targetAppId, int ephemeralAppId) {
8718         getPackageManagerInternalLocked().
8719                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8720     }
8721
8722     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8723         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8724         if (targetUris != null) {
8725             return targetUris.get(grantUri);
8726         }
8727         return null;
8728     }
8729
8730     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8731             String targetPkg, int targetUid, GrantUri grantUri) {
8732         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8733         if (targetUris == null) {
8734             targetUris = Maps.newArrayMap();
8735             mGrantedUriPermissions.put(targetUid, targetUris);
8736         }
8737
8738         UriPermission perm = targetUris.get(grantUri);
8739         if (perm == null) {
8740             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8741             targetUris.put(grantUri, perm);
8742         }
8743
8744         return perm;
8745     }
8746
8747     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8748             final int modeFlags) {
8749         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8750         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8751                 : UriPermission.STRENGTH_OWNED;
8752
8753         // Root gets to do everything.
8754         if (uid == 0) {
8755             return true;
8756         }
8757
8758         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8759         if (perms == null) return false;
8760
8761         // First look for exact match
8762         final UriPermission exactPerm = perms.get(grantUri);
8763         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8764             return true;
8765         }
8766
8767         // No exact match, look for prefixes
8768         final int N = perms.size();
8769         for (int i = 0; i < N; i++) {
8770             final UriPermission perm = perms.valueAt(i);
8771             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8772                     && perm.getStrength(modeFlags) >= minStrength) {
8773                 return true;
8774             }
8775         }
8776
8777         return false;
8778     }
8779
8780     /**
8781      * @param uri This uri must NOT contain an embedded userId.
8782      * @param userId The userId in which the uri is to be resolved.
8783      */
8784     @Override
8785     public int checkUriPermission(Uri uri, int pid, int uid,
8786             final int modeFlags, int userId, IBinder callerToken) {
8787         enforceNotIsolatedCaller("checkUriPermission");
8788
8789         // Another redirected-binder-call permissions check as in
8790         // {@link checkPermissionWithToken}.
8791         Identity tlsIdentity = sCallerIdentity.get();
8792         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8793             uid = tlsIdentity.uid;
8794             pid = tlsIdentity.pid;
8795         }
8796
8797         // Our own process gets to do everything.
8798         if (pid == MY_PID) {
8799             return PackageManager.PERMISSION_GRANTED;
8800         }
8801         synchronized (this) {
8802             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8803                     ? PackageManager.PERMISSION_GRANTED
8804                     : PackageManager.PERMISSION_DENIED;
8805         }
8806     }
8807
8808     /**
8809      * Check if the targetPkg can be granted permission to access uri by
8810      * the callingUid using the given modeFlags.  Throws a security exception
8811      * if callingUid is not allowed to do this.  Returns the uid of the target
8812      * if the URI permission grant should be performed; returns -1 if it is not
8813      * needed (for example targetPkg already has permission to access the URI).
8814      * If you already know the uid of the target, you can supply it in
8815      * lastTargetUid else set that to -1.
8816      */
8817     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8818             final int modeFlags, int lastTargetUid) {
8819         if (!Intent.isAccessUriMode(modeFlags)) {
8820             return -1;
8821         }
8822
8823         if (targetPkg != null) {
8824             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8825                     "Checking grant " + targetPkg + " permission to " + grantUri);
8826         }
8827
8828         final IPackageManager pm = AppGlobals.getPackageManager();
8829
8830         // If this is not a content: uri, we can't do anything with it.
8831         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8832             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8833                     "Can't grant URI permission for non-content URI: " + grantUri);
8834             return -1;
8835         }
8836
8837         // Bail early if system is trying to hand out permissions directly; it
8838         // must always grant permissions on behalf of someone explicit.
8839         final int callingAppId = UserHandle.getAppId(callingUid);
8840         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8841             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8842                 // Exempted authority for cropping user photos in Settings app
8843             } else {
8844                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8845                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8846                 return -1;
8847             }
8848         }
8849
8850         final String authority = grantUri.uri.getAuthority();
8851         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8852                 MATCH_DEBUG_TRIAGED_MISSING);
8853         if (pi == null) {
8854             Slog.w(TAG, "No content provider found for permission check: " +
8855                     grantUri.uri.toSafeString());
8856             return -1;
8857         }
8858
8859         int targetUid = lastTargetUid;
8860         if (targetUid < 0 && targetPkg != null) {
8861             try {
8862                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8863                         UserHandle.getUserId(callingUid));
8864                 if (targetUid < 0) {
8865                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8866                             "Can't grant URI permission no uid for: " + targetPkg);
8867                     return -1;
8868                 }
8869             } catch (RemoteException ex) {
8870                 return -1;
8871             }
8872         }
8873
8874         // If we're extending a persistable grant, then we always need to create
8875         // the grant data structure so that take/release APIs work
8876         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8877             return targetUid;
8878         }
8879
8880         if (targetUid >= 0) {
8881             // First...  does the target actually need this permission?
8882             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8883                 // No need to grant the target this permission.
8884                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8885                         "Target " + targetPkg + " already has full permission to " + grantUri);
8886                 return -1;
8887             }
8888         } else {
8889             // First...  there is no target package, so can anyone access it?
8890             boolean allowed = pi.exported;
8891             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8892                 if (pi.readPermission != null) {
8893                     allowed = false;
8894                 }
8895             }
8896             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8897                 if (pi.writePermission != null) {
8898                     allowed = false;
8899                 }
8900             }
8901             if (allowed) {
8902                 return -1;
8903             }
8904         }
8905
8906         /* There is a special cross user grant if:
8907          * - The target is on another user.
8908          * - Apps on the current user can access the uri without any uid permissions.
8909          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8910          * grant uri permissions.
8911          */
8912         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8913                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8914                 modeFlags, false /*without considering the uid permissions*/);
8915
8916         // Second...  is the provider allowing granting of URI permissions?
8917         if (!specialCrossUserGrant) {
8918             if (!pi.grantUriPermissions) {
8919                 throw new SecurityException("Provider " + pi.packageName
8920                         + "/" + pi.name
8921                         + " does not allow granting of Uri permissions (uri "
8922                         + grantUri + ")");
8923             }
8924             if (pi.uriPermissionPatterns != null) {
8925                 final int N = pi.uriPermissionPatterns.length;
8926                 boolean allowed = false;
8927                 for (int i=0; i<N; i++) {
8928                     if (pi.uriPermissionPatterns[i] != null
8929                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8930                         allowed = true;
8931                         break;
8932                     }
8933                 }
8934                 if (!allowed) {
8935                     throw new SecurityException("Provider " + pi.packageName
8936                             + "/" + pi.name
8937                             + " does not allow granting of permission to path of Uri "
8938                             + grantUri);
8939                 }
8940             }
8941         }
8942
8943         // Third...  does the caller itself have permission to access
8944         // this uri?
8945         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8946             // Require they hold a strong enough Uri permission
8947             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8948                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8949                     throw new SecurityException(
8950                             "UID " + callingUid + " does not have permission to " + grantUri
8951                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8952                                     + "or related APIs");
8953                 } else {
8954                     throw new SecurityException(
8955                             "UID " + callingUid + " does not have permission to " + grantUri);
8956                 }
8957             }
8958         }
8959         return targetUid;
8960     }
8961
8962     /**
8963      * @param uri This uri must NOT contain an embedded userId.
8964      * @param userId The userId in which the uri is to be resolved.
8965      */
8966     @Override
8967     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8968             final int modeFlags, int userId) {
8969         enforceNotIsolatedCaller("checkGrantUriPermission");
8970         synchronized(this) {
8971             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8972                     new GrantUri(userId, uri, false), modeFlags, -1);
8973         }
8974     }
8975
8976     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8977             final int modeFlags, UriPermissionOwner owner) {
8978         if (!Intent.isAccessUriMode(modeFlags)) {
8979             return;
8980         }
8981
8982         // So here we are: the caller has the assumed permission
8983         // to the uri, and the target doesn't.  Let's now give this to
8984         // the target.
8985
8986         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8987                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8988
8989         final String authority = grantUri.uri.getAuthority();
8990         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8991                 MATCH_DEBUG_TRIAGED_MISSING);
8992         if (pi == null) {
8993             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8994             return;
8995         }
8996
8997         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8998             grantUri.prefix = true;
8999         }
9000         final UriPermission perm = findOrCreateUriPermissionLocked(
9001                 pi.packageName, targetPkg, targetUid, grantUri);
9002         perm.grantModes(modeFlags, owner);
9003     }
9004
9005     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
9006             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
9007         if (targetPkg == null) {
9008             throw new NullPointerException("targetPkg");
9009         }
9010         int targetUid;
9011         final IPackageManager pm = AppGlobals.getPackageManager();
9012         try {
9013             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9014         } catch (RemoteException ex) {
9015             return;
9016         }
9017
9018         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9019                 targetUid);
9020         if (targetUid < 0) {
9021             return;
9022         }
9023
9024         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9025                 owner);
9026     }
9027
9028     static class NeededUriGrants extends ArrayList<GrantUri> {
9029         final String targetPkg;
9030         final int targetUid;
9031         final int flags;
9032
9033         NeededUriGrants(String targetPkg, int targetUid, int flags) {
9034             this.targetPkg = targetPkg;
9035             this.targetUid = targetUid;
9036             this.flags = flags;
9037         }
9038     }
9039
9040     /**
9041      * Like checkGrantUriPermissionLocked, but takes an Intent.
9042      */
9043     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9044             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9045         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9046                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9047                 + " clip=" + (intent != null ? intent.getClipData() : null)
9048                 + " from " + intent + "; flags=0x"
9049                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9050
9051         if (targetPkg == null) {
9052             throw new NullPointerException("targetPkg");
9053         }
9054
9055         if (intent == null) {
9056             return null;
9057         }
9058         Uri data = intent.getData();
9059         ClipData clip = intent.getClipData();
9060         if (data == null && clip == null) {
9061             return null;
9062         }
9063         // Default userId for uris in the intent (if they don't specify it themselves)
9064         int contentUserHint = intent.getContentUserHint();
9065         if (contentUserHint == UserHandle.USER_CURRENT) {
9066             contentUserHint = UserHandle.getUserId(callingUid);
9067         }
9068         final IPackageManager pm = AppGlobals.getPackageManager();
9069         int targetUid;
9070         if (needed != null) {
9071             targetUid = needed.targetUid;
9072         } else {
9073             try {
9074                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9075                         targetUserId);
9076             } catch (RemoteException ex) {
9077                 return null;
9078             }
9079             if (targetUid < 0) {
9080                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9081                         "Can't grant URI permission no uid for: " + targetPkg
9082                         + " on user " + targetUserId);
9083                 return null;
9084             }
9085         }
9086         if (data != null) {
9087             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9088             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9089                     targetUid);
9090             if (targetUid > 0) {
9091                 if (needed == null) {
9092                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9093                 }
9094                 needed.add(grantUri);
9095             }
9096         }
9097         if (clip != null) {
9098             for (int i=0; i<clip.getItemCount(); i++) {
9099                 Uri uri = clip.getItemAt(i).getUri();
9100                 if (uri != null) {
9101                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9102                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9103                             targetUid);
9104                     if (targetUid > 0) {
9105                         if (needed == null) {
9106                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9107                         }
9108                         needed.add(grantUri);
9109                     }
9110                 } else {
9111                     Intent clipIntent = clip.getItemAt(i).getIntent();
9112                     if (clipIntent != null) {
9113                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9114                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9115                         if (newNeeded != null) {
9116                             needed = newNeeded;
9117                         }
9118                     }
9119                 }
9120             }
9121         }
9122
9123         return needed;
9124     }
9125
9126     /**
9127      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9128      */
9129     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9130             UriPermissionOwner owner) {
9131         if (needed != null) {
9132             for (int i=0; i<needed.size(); i++) {
9133                 GrantUri grantUri = needed.get(i);
9134                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9135                         grantUri, needed.flags, owner);
9136             }
9137         }
9138     }
9139
9140     void grantUriPermissionFromIntentLocked(int callingUid,
9141             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9142         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9143                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9144         if (needed == null) {
9145             return;
9146         }
9147
9148         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9149     }
9150
9151     /**
9152      * @param uri This uri must NOT contain an embedded userId.
9153      * @param userId The userId in which the uri is to be resolved.
9154      */
9155     @Override
9156     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9157             final int modeFlags, int userId) {
9158         enforceNotIsolatedCaller("grantUriPermission");
9159         GrantUri grantUri = new GrantUri(userId, uri, false);
9160         synchronized(this) {
9161             final ProcessRecord r = getRecordForAppLocked(caller);
9162             if (r == null) {
9163                 throw new SecurityException("Unable to find app for caller "
9164                         + caller
9165                         + " when granting permission to uri " + grantUri);
9166             }
9167             if (targetPkg == null) {
9168                 throw new IllegalArgumentException("null target");
9169             }
9170             if (grantUri == null) {
9171                 throw new IllegalArgumentException("null uri");
9172             }
9173
9174             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9175                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9176                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9177                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9178
9179             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9180                     UserHandle.getUserId(r.uid));
9181         }
9182     }
9183
9184     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9185         if (perm.modeFlags == 0) {
9186             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9187                     perm.targetUid);
9188             if (perms != null) {
9189                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9190                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9191
9192                 perms.remove(perm.uri);
9193                 if (perms.isEmpty()) {
9194                     mGrantedUriPermissions.remove(perm.targetUid);
9195                 }
9196             }
9197         }
9198     }
9199
9200     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9201             final int modeFlags) {
9202         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9203                 "Revoking all granted permissions to " + grantUri);
9204
9205         final IPackageManager pm = AppGlobals.getPackageManager();
9206         final String authority = grantUri.uri.getAuthority();
9207         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9208                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9209         if (pi == null) {
9210             Slog.w(TAG, "No content provider found for permission revoke: "
9211                     + grantUri.toSafeString());
9212             return;
9213         }
9214
9215         // Does the caller have this permission on the URI?
9216         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9217             // If they don't have direct access to the URI, then revoke any
9218             // ownerless URI permissions that have been granted to them.
9219             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9220             if (perms != null) {
9221                 boolean persistChanged = false;
9222                 for (int i = perms.size()-1; i >= 0; i--) {
9223                     final UriPermission perm = perms.valueAt(i);
9224                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9225                         continue;
9226                     }
9227                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9228                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9229                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9230                                 "Revoking non-owned " + perm.targetUid
9231                                 + " permission to " + perm.uri);
9232                         persistChanged |= perm.revokeModes(
9233                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9234                         if (perm.modeFlags == 0) {
9235                             perms.removeAt(i);
9236                         }
9237                     }
9238                 }
9239                 if (perms.isEmpty()) {
9240                     mGrantedUriPermissions.remove(callingUid);
9241                 }
9242                 if (persistChanged) {
9243                     schedulePersistUriGrants();
9244                 }
9245             }
9246             return;
9247         }
9248
9249         boolean persistChanged = false;
9250
9251         // Go through all of the permissions and remove any that match.
9252         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9253             final int targetUid = mGrantedUriPermissions.keyAt(i);
9254             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9255
9256             for (int j = perms.size()-1; j >= 0; j--) {
9257                 final UriPermission perm = perms.valueAt(j);
9258                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9259                     continue;
9260                 }
9261                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9262                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9263                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9264                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9265                     persistChanged |= perm.revokeModes(
9266                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9267                             targetPackage == null);
9268                     if (perm.modeFlags == 0) {
9269                         perms.removeAt(j);
9270                     }
9271                 }
9272             }
9273
9274             if (perms.isEmpty()) {
9275                 mGrantedUriPermissions.removeAt(i);
9276             }
9277         }
9278
9279         if (persistChanged) {
9280             schedulePersistUriGrants();
9281         }
9282     }
9283
9284     /**
9285      * @param uri This uri must NOT contain an embedded userId.
9286      * @param userId The userId in which the uri is to be resolved.
9287      */
9288     @Override
9289     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9290             final int modeFlags, int userId) {
9291         enforceNotIsolatedCaller("revokeUriPermission");
9292         synchronized(this) {
9293             final ProcessRecord r = getRecordForAppLocked(caller);
9294             if (r == null) {
9295                 throw new SecurityException("Unable to find app for caller "
9296                         + caller
9297                         + " when revoking permission to uri " + uri);
9298             }
9299             if (uri == null) {
9300                 Slog.w(TAG, "revokeUriPermission: null uri");
9301                 return;
9302             }
9303
9304             if (!Intent.isAccessUriMode(modeFlags)) {
9305                 return;
9306             }
9307
9308             final String authority = uri.getAuthority();
9309             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9310                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9311             if (pi == null) {
9312                 Slog.w(TAG, "No content provider found for permission revoke: "
9313                         + uri.toSafeString());
9314                 return;
9315             }
9316
9317             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9318                     modeFlags);
9319         }
9320     }
9321
9322     /**
9323      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9324      * given package.
9325      *
9326      * @param packageName Package name to match, or {@code null} to apply to all
9327      *            packages.
9328      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9329      *            to all users.
9330      * @param persistable If persistable grants should be removed.
9331      */
9332     private void removeUriPermissionsForPackageLocked(
9333             String packageName, int userHandle, boolean persistable) {
9334         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9335             throw new IllegalArgumentException("Must narrow by either package or user");
9336         }
9337
9338         boolean persistChanged = false;
9339
9340         int N = mGrantedUriPermissions.size();
9341         for (int i = 0; i < N; i++) {
9342             final int targetUid = mGrantedUriPermissions.keyAt(i);
9343             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9344
9345             // Only inspect grants matching user
9346             if (userHandle == UserHandle.USER_ALL
9347                     || userHandle == UserHandle.getUserId(targetUid)) {
9348                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9349                     final UriPermission perm = it.next();
9350
9351                     // Only inspect grants matching package
9352                     if (packageName == null || perm.sourcePkg.equals(packageName)
9353                             || perm.targetPkg.equals(packageName)) {
9354                         // Hacky solution as part of fixing a security bug; ignore
9355                         // grants associated with DownloadManager so we don't have
9356                         // to immediately launch it to regrant the permissions
9357                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9358                                 && !persistable) continue;
9359
9360                         persistChanged |= perm.revokeModes(persistable
9361                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9362
9363                         // Only remove when no modes remain; any persisted grants
9364                         // will keep this alive.
9365                         if (perm.modeFlags == 0) {
9366                             it.remove();
9367                         }
9368                     }
9369                 }
9370
9371                 if (perms.isEmpty()) {
9372                     mGrantedUriPermissions.remove(targetUid);
9373                     N--;
9374                     i--;
9375                 }
9376             }
9377         }
9378
9379         if (persistChanged) {
9380             schedulePersistUriGrants();
9381         }
9382     }
9383
9384     @Override
9385     public IBinder newUriPermissionOwner(String name) {
9386         enforceNotIsolatedCaller("newUriPermissionOwner");
9387         synchronized(this) {
9388             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9389             return owner.getExternalTokenLocked();
9390         }
9391     }
9392
9393     @Override
9394     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9395         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9396         synchronized(this) {
9397             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9398             if (r == null) {
9399                 throw new IllegalArgumentException("Activity does not exist; token="
9400                         + activityToken);
9401             }
9402             return r.getUriPermissionsLocked().getExternalTokenLocked();
9403         }
9404     }
9405     /**
9406      * @param uri This uri must NOT contain an embedded userId.
9407      * @param sourceUserId The userId in which the uri is to be resolved.
9408      * @param targetUserId The userId of the app that receives the grant.
9409      */
9410     @Override
9411     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9412             final int modeFlags, int sourceUserId, int targetUserId) {
9413         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9414                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9415                 "grantUriPermissionFromOwner", null);
9416         synchronized(this) {
9417             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9418             if (owner == null) {
9419                 throw new IllegalArgumentException("Unknown owner: " + token);
9420             }
9421             if (fromUid != Binder.getCallingUid()) {
9422                 if (Binder.getCallingUid() != myUid()) {
9423                     // Only system code can grant URI permissions on behalf
9424                     // of other users.
9425                     throw new SecurityException("nice try");
9426                 }
9427             }
9428             if (targetPkg == null) {
9429                 throw new IllegalArgumentException("null target");
9430             }
9431             if (uri == null) {
9432                 throw new IllegalArgumentException("null uri");
9433             }
9434
9435             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9436                     modeFlags, owner, targetUserId);
9437         }
9438     }
9439
9440     /**
9441      * @param uri This uri must NOT contain an embedded userId.
9442      * @param userId The userId in which the uri is to be resolved.
9443      */
9444     @Override
9445     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9446         synchronized(this) {
9447             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9448             if (owner == null) {
9449                 throw new IllegalArgumentException("Unknown owner: " + token);
9450             }
9451
9452             if (uri == null) {
9453                 owner.removeUriPermissionsLocked(mode);
9454             } else {
9455                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9456                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9457             }
9458         }
9459     }
9460
9461     private void schedulePersistUriGrants() {
9462         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9463             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9464                     10 * DateUtils.SECOND_IN_MILLIS);
9465         }
9466     }
9467
9468     private void writeGrantedUriPermissions() {
9469         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9470
9471         // Snapshot permissions so we can persist without lock
9472         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9473         synchronized (this) {
9474             final int size = mGrantedUriPermissions.size();
9475             for (int i = 0; i < size; i++) {
9476                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9477                 for (UriPermission perm : perms.values()) {
9478                     if (perm.persistedModeFlags != 0) {
9479                         persist.add(perm.snapshot());
9480                     }
9481                 }
9482             }
9483         }
9484
9485         FileOutputStream fos = null;
9486         try {
9487             fos = mGrantFile.startWrite();
9488
9489             XmlSerializer out = new FastXmlSerializer();
9490             out.setOutput(fos, StandardCharsets.UTF_8.name());
9491             out.startDocument(null, true);
9492             out.startTag(null, TAG_URI_GRANTS);
9493             for (UriPermission.Snapshot perm : persist) {
9494                 out.startTag(null, TAG_URI_GRANT);
9495                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9496                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9497                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9498                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9499                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9500                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9501                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9502                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9503                 out.endTag(null, TAG_URI_GRANT);
9504             }
9505             out.endTag(null, TAG_URI_GRANTS);
9506             out.endDocument();
9507
9508             mGrantFile.finishWrite(fos);
9509         } catch (IOException e) {
9510             if (fos != null) {
9511                 mGrantFile.failWrite(fos);
9512             }
9513         }
9514     }
9515
9516     private void readGrantedUriPermissionsLocked() {
9517         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9518
9519         final long now = System.currentTimeMillis();
9520
9521         FileInputStream fis = null;
9522         try {
9523             fis = mGrantFile.openRead();
9524             final XmlPullParser in = Xml.newPullParser();
9525             in.setInput(fis, StandardCharsets.UTF_8.name());
9526
9527             int type;
9528             while ((type = in.next()) != END_DOCUMENT) {
9529                 final String tag = in.getName();
9530                 if (type == START_TAG) {
9531                     if (TAG_URI_GRANT.equals(tag)) {
9532                         final int sourceUserId;
9533                         final int targetUserId;
9534                         final int userHandle = readIntAttribute(in,
9535                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9536                         if (userHandle != UserHandle.USER_NULL) {
9537                             // For backwards compatibility.
9538                             sourceUserId = userHandle;
9539                             targetUserId = userHandle;
9540                         } else {
9541                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9542                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9543                         }
9544                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9545                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9546                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9547                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9548                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9549                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9550
9551                         // Sanity check that provider still belongs to source package
9552                         // Both direct boot aware and unaware packages are fine as we
9553                         // will do filtering at query time to avoid multiple parsing.
9554                         final ProviderInfo pi = getProviderInfoLocked(
9555                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9556                                         | MATCH_DIRECT_BOOT_UNAWARE);
9557                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9558                             int targetUid = -1;
9559                             try {
9560                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9561                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9562                             } catch (RemoteException e) {
9563                             }
9564                             if (targetUid != -1) {
9565                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9566                                         sourcePkg, targetPkg, targetUid,
9567                                         new GrantUri(sourceUserId, uri, prefix));
9568                                 perm.initPersistedModes(modeFlags, createdTime);
9569                             }
9570                         } else {
9571                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9572                                     + " but instead found " + pi);
9573                         }
9574                     }
9575                 }
9576             }
9577         } catch (FileNotFoundException e) {
9578             // Missing grants is okay
9579         } catch (IOException e) {
9580             Slog.wtf(TAG, "Failed reading Uri grants", e);
9581         } catch (XmlPullParserException e) {
9582             Slog.wtf(TAG, "Failed reading Uri grants", e);
9583         } finally {
9584             IoUtils.closeQuietly(fis);
9585         }
9586     }
9587
9588     /**
9589      * @param uri This uri must NOT contain an embedded userId.
9590      * @param userId The userId in which the uri is to be resolved.
9591      */
9592     @Override
9593     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9594         enforceNotIsolatedCaller("takePersistableUriPermission");
9595
9596         Preconditions.checkFlagsArgument(modeFlags,
9597                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9598
9599         synchronized (this) {
9600             final int callingUid = Binder.getCallingUid();
9601             boolean persistChanged = false;
9602             GrantUri grantUri = new GrantUri(userId, uri, false);
9603
9604             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9605                     new GrantUri(userId, uri, false));
9606             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9607                     new GrantUri(userId, uri, true));
9608
9609             final boolean exactValid = (exactPerm != null)
9610                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9611             final boolean prefixValid = (prefixPerm != null)
9612                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9613
9614             if (!(exactValid || prefixValid)) {
9615                 throw new SecurityException("No persistable permission grants found for UID "
9616                         + callingUid + " and Uri " + grantUri.toSafeString());
9617             }
9618
9619             if (exactValid) {
9620                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9621             }
9622             if (prefixValid) {
9623                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9624             }
9625
9626             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9627
9628             if (persistChanged) {
9629                 schedulePersistUriGrants();
9630             }
9631         }
9632     }
9633
9634     /**
9635      * @param uri This uri must NOT contain an embedded userId.
9636      * @param userId The userId in which the uri is to be resolved.
9637      */
9638     @Override
9639     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9640         enforceNotIsolatedCaller("releasePersistableUriPermission");
9641
9642         Preconditions.checkFlagsArgument(modeFlags,
9643                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9644
9645         synchronized (this) {
9646             final int callingUid = Binder.getCallingUid();
9647             boolean persistChanged = false;
9648
9649             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9650                     new GrantUri(userId, uri, false));
9651             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9652                     new GrantUri(userId, uri, true));
9653             if (exactPerm == null && prefixPerm == null) {
9654                 throw new SecurityException("No permission grants found for UID " + callingUid
9655                         + " and Uri " + uri.toSafeString());
9656             }
9657
9658             if (exactPerm != null) {
9659                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9660                 removeUriPermissionIfNeededLocked(exactPerm);
9661             }
9662             if (prefixPerm != null) {
9663                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9664                 removeUriPermissionIfNeededLocked(prefixPerm);
9665             }
9666
9667             if (persistChanged) {
9668                 schedulePersistUriGrants();
9669             }
9670         }
9671     }
9672
9673     /**
9674      * Prune any older {@link UriPermission} for the given UID until outstanding
9675      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9676      *
9677      * @return if any mutations occured that require persisting.
9678      */
9679     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9680         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9681         if (perms == null) return false;
9682         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9683
9684         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9685         for (UriPermission perm : perms.values()) {
9686             if (perm.persistedModeFlags != 0) {
9687                 persisted.add(perm);
9688             }
9689         }
9690
9691         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9692         if (trimCount <= 0) return false;
9693
9694         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9695         for (int i = 0; i < trimCount; i++) {
9696             final UriPermission perm = persisted.get(i);
9697
9698             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9699                     "Trimming grant created at " + perm.persistedCreateTime);
9700
9701             perm.releasePersistableModes(~0);
9702             removeUriPermissionIfNeededLocked(perm);
9703         }
9704
9705         return true;
9706     }
9707
9708     @Override
9709     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9710             String packageName, boolean incoming) {
9711         enforceNotIsolatedCaller("getPersistedUriPermissions");
9712         Preconditions.checkNotNull(packageName, "packageName");
9713
9714         final int callingUid = Binder.getCallingUid();
9715         final int callingUserId = UserHandle.getUserId(callingUid);
9716         final IPackageManager pm = AppGlobals.getPackageManager();
9717         try {
9718             final int packageUid = pm.getPackageUid(packageName,
9719                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9720             if (packageUid != callingUid) {
9721                 throw new SecurityException(
9722                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9723             }
9724         } catch (RemoteException e) {
9725             throw new SecurityException("Failed to verify package name ownership");
9726         }
9727
9728         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9729         synchronized (this) {
9730             if (incoming) {
9731                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9732                         callingUid);
9733                 if (perms == null) {
9734                     Slog.w(TAG, "No permission grants found for " + packageName);
9735                 } else {
9736                     for (UriPermission perm : perms.values()) {
9737                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9738                             result.add(perm.buildPersistedPublicApiObject());
9739                         }
9740                     }
9741                 }
9742             } else {
9743                 final int size = mGrantedUriPermissions.size();
9744                 for (int i = 0; i < size; i++) {
9745                     final ArrayMap<GrantUri, UriPermission> perms =
9746                             mGrantedUriPermissions.valueAt(i);
9747                     for (UriPermission perm : perms.values()) {
9748                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9749                             result.add(perm.buildPersistedPublicApiObject());
9750                         }
9751                     }
9752                 }
9753             }
9754         }
9755         return new ParceledListSlice<android.content.UriPermission>(result);
9756     }
9757
9758     @Override
9759     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9760             String packageName, int userId) {
9761         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9762                 "getGrantedUriPermissions");
9763
9764         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9765         synchronized (this) {
9766             final int size = mGrantedUriPermissions.size();
9767             for (int i = 0; i < size; i++) {
9768                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9769                 for (UriPermission perm : perms.values()) {
9770                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9771                             && perm.persistedModeFlags != 0) {
9772                         result.add(perm.buildPersistedPublicApiObject());
9773                     }
9774                 }
9775             }
9776         }
9777         return new ParceledListSlice<android.content.UriPermission>(result);
9778     }
9779
9780     @Override
9781     public void clearGrantedUriPermissions(String packageName, int userId) {
9782         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9783                 "clearGrantedUriPermissions");
9784         removeUriPermissionsForPackageLocked(packageName, userId, true);
9785     }
9786
9787     @Override
9788     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9789         synchronized (this) {
9790             ProcessRecord app =
9791                 who != null ? getRecordForAppLocked(who) : null;
9792             if (app == null) return;
9793
9794             Message msg = Message.obtain();
9795             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9796             msg.obj = app;
9797             msg.arg1 = waiting ? 1 : 0;
9798             mUiHandler.sendMessage(msg);
9799         }
9800     }
9801
9802     @Override
9803     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9804         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9805         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9806         outInfo.availMem = getFreeMemory();
9807         outInfo.totalMem = getTotalMemory();
9808         outInfo.threshold = homeAppMem;
9809         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9810         outInfo.hiddenAppThreshold = cachedAppMem;
9811         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9812                 ProcessList.SERVICE_ADJ);
9813         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9814                 ProcessList.VISIBLE_APP_ADJ);
9815         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9816                 ProcessList.FOREGROUND_APP_ADJ);
9817     }
9818
9819     // =========================================================
9820     // TASK MANAGEMENT
9821     // =========================================================
9822
9823     @Override
9824     public List<IBinder> getAppTasks(String callingPackage) {
9825         int callingUid = Binder.getCallingUid();
9826         long ident = Binder.clearCallingIdentity();
9827
9828         synchronized(this) {
9829             ArrayList<IBinder> list = new ArrayList<IBinder>();
9830             try {
9831                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9832
9833                 final int N = mRecentTasks.size();
9834                 for (int i = 0; i < N; i++) {
9835                     TaskRecord tr = mRecentTasks.get(i);
9836                     // Skip tasks that do not match the caller.  We don't need to verify
9837                     // callingPackage, because we are also limiting to callingUid and know
9838                     // that will limit to the correct security sandbox.
9839                     if (tr.effectiveUid != callingUid) {
9840                         continue;
9841                     }
9842                     Intent intent = tr.getBaseIntent();
9843                     if (intent == null ||
9844                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9845                         continue;
9846                     }
9847                     ActivityManager.RecentTaskInfo taskInfo =
9848                             createRecentTaskInfoFromTaskRecord(tr);
9849                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9850                     list.add(taskImpl.asBinder());
9851                 }
9852             } finally {
9853                 Binder.restoreCallingIdentity(ident);
9854             }
9855             return list;
9856         }
9857     }
9858
9859     @Override
9860     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9861         final int callingUid = Binder.getCallingUid();
9862         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9863
9864         synchronized(this) {
9865             if (DEBUG_ALL) Slog.v(
9866                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9867
9868             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9869                     callingUid);
9870
9871             // TODO: Improve with MRU list from all ActivityStacks.
9872             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9873         }
9874
9875         return list;
9876     }
9877
9878     /**
9879      * Creates a new RecentTaskInfo from a TaskRecord.
9880      */
9881     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9882         // Update the task description to reflect any changes in the task stack
9883         tr.updateTaskDescription();
9884
9885         // Compose the recent task info
9886         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9887         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9888         rti.persistentId = tr.taskId;
9889         rti.baseIntent = new Intent(tr.getBaseIntent());
9890         rti.origActivity = tr.origActivity;
9891         rti.realActivity = tr.realActivity;
9892         rti.description = tr.lastDescription;
9893         rti.stackId = tr.getStackId();
9894         rti.userId = tr.userId;
9895         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9896         rti.firstActiveTime = tr.firstActiveTime;
9897         rti.lastActiveTime = tr.lastActiveTime;
9898         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9899         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9900         rti.numActivities = 0;
9901         if (tr.mBounds != null) {
9902             rti.bounds = new Rect(tr.mBounds);
9903         }
9904         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9905         rti.resizeMode = tr.mResizeMode;
9906
9907         ActivityRecord base = null;
9908         ActivityRecord top = null;
9909         ActivityRecord tmp;
9910
9911         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9912             tmp = tr.mActivities.get(i);
9913             if (tmp.finishing) {
9914                 continue;
9915             }
9916             base = tmp;
9917             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9918                 top = base;
9919             }
9920             rti.numActivities++;
9921         }
9922
9923         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9924         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9925
9926         return rti;
9927     }
9928
9929     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9930         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9931                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9932         if (!allowed) {
9933             if (checkPermission(android.Manifest.permission.GET_TASKS,
9934                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9935                 // Temporary compatibility: some existing apps on the system image may
9936                 // still be requesting the old permission and not switched to the new
9937                 // one; if so, we'll still allow them full access.  This means we need
9938                 // to see if they are holding the old permission and are a system app.
9939                 try {
9940                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9941                         allowed = true;
9942                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9943                                 + " is using old GET_TASKS but privileged; allowing");
9944                     }
9945                 } catch (RemoteException e) {
9946                 }
9947             }
9948         }
9949         if (!allowed) {
9950             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9951                     + " does not hold REAL_GET_TASKS; limiting output");
9952         }
9953         return allowed;
9954     }
9955
9956     @Override
9957     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9958             int userId) {
9959         final int callingUid = Binder.getCallingUid();
9960         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9961                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9962
9963         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9964         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9965         synchronized (this) {
9966             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9967                     callingUid);
9968             final boolean detailed = checkCallingPermission(
9969                     android.Manifest.permission.GET_DETAILED_TASKS)
9970                     == PackageManager.PERMISSION_GRANTED;
9971
9972             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9973                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9974                 return ParceledListSlice.emptyList();
9975             }
9976             mRecentTasks.loadUserRecentsLocked(userId);
9977
9978             final int recentsCount = mRecentTasks.size();
9979             ArrayList<ActivityManager.RecentTaskInfo> res =
9980                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9981
9982             final Set<Integer> includedUsers;
9983             if (includeProfiles) {
9984                 includedUsers = mUserController.getProfileIds(userId);
9985             } else {
9986                 includedUsers = new HashSet<>();
9987             }
9988             includedUsers.add(Integer.valueOf(userId));
9989
9990             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9991                 TaskRecord tr = mRecentTasks.get(i);
9992                 // Only add calling user or related users recent tasks
9993                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9994                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9995                     continue;
9996                 }
9997
9998                 if (tr.realActivitySuspended) {
9999                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
10000                     continue;
10001                 }
10002
10003                 // Return the entry if desired by the caller.  We always return
10004                 // the first entry, because callers always expect this to be the
10005                 // foreground app.  We may filter others if the caller has
10006                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
10007                 // we should exclude the entry.
10008
10009                 if (i == 0
10010                         || withExcluded
10011                         || (tr.intent == null)
10012                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
10013                                 == 0)) {
10014                     if (!allowed) {
10015                         // If the caller doesn't have the GET_TASKS permission, then only
10016                         // allow them to see a small subset of tasks -- their own and home.
10017                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
10018                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10019                             continue;
10020                         }
10021                     }
10022                     final ActivityStack stack = tr.getStack();
10023                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10024                         if (stack != null && stack.isHomeOrRecentsStack()) {
10025                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10026                                     "Skipping, home or recents stack task: " + tr);
10027                             continue;
10028                         }
10029                     }
10030                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10031                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10032                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10033                                     "Skipping, top task in docked stack: " + tr);
10034                             continue;
10035                         }
10036                     }
10037                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10038                         if (stack != null && stack.isPinnedStack()) {
10039                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10040                                     "Skipping, pinned stack task: " + tr);
10041                             continue;
10042                         }
10043                     }
10044                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10045                         // Don't include auto remove tasks that are finished or finishing.
10046                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10047                                 "Skipping, auto-remove without activity: " + tr);
10048                         continue;
10049                     }
10050                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10051                             && !tr.isAvailable) {
10052                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10053                                 "Skipping, unavail real act: " + tr);
10054                         continue;
10055                     }
10056
10057                     if (!tr.mUserSetupComplete) {
10058                         // Don't include task launched while user is not done setting-up.
10059                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10060                                 "Skipping, user setup not complete: " + tr);
10061                         continue;
10062                     }
10063
10064                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10065                     if (!detailed) {
10066                         rti.baseIntent.replaceExtras((Bundle)null);
10067                     }
10068
10069                     res.add(rti);
10070                     maxNum--;
10071                 }
10072             }
10073             return new ParceledListSlice<>(res);
10074         }
10075     }
10076
10077     @Override
10078     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10079         synchronized (this) {
10080             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10081                     "getTaskThumbnail()");
10082             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10083                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10084             if (tr != null) {
10085                 return tr.getTaskThumbnailLocked();
10086             }
10087         }
10088         return null;
10089     }
10090
10091     @Override
10092     public ActivityManager.TaskDescription getTaskDescription(int id) {
10093         synchronized (this) {
10094             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10095                     "getTaskDescription()");
10096             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10097                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10098             if (tr != null) {
10099                 return tr.lastTaskDescription;
10100             }
10101         }
10102         return null;
10103     }
10104
10105     @Override
10106     public int addAppTask(IBinder activityToken, Intent intent,
10107             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10108         final int callingUid = Binder.getCallingUid();
10109         final long callingIdent = Binder.clearCallingIdentity();
10110
10111         try {
10112             synchronized (this) {
10113                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10114                 if (r == null) {
10115                     throw new IllegalArgumentException("Activity does not exist; token="
10116                             + activityToken);
10117                 }
10118                 ComponentName comp = intent.getComponent();
10119                 if (comp == null) {
10120                     throw new IllegalArgumentException("Intent " + intent
10121                             + " must specify explicit component");
10122                 }
10123                 if (thumbnail.getWidth() != mThumbnailWidth
10124                         || thumbnail.getHeight() != mThumbnailHeight) {
10125                     throw new IllegalArgumentException("Bad thumbnail size: got "
10126                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10127                             + mThumbnailWidth + "x" + mThumbnailHeight);
10128                 }
10129                 if (intent.getSelector() != null) {
10130                     intent.setSelector(null);
10131                 }
10132                 if (intent.getSourceBounds() != null) {
10133                     intent.setSourceBounds(null);
10134                 }
10135                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10136                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10137                         // The caller has added this as an auto-remove task...  that makes no
10138                         // sense, so turn off auto-remove.
10139                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10140                     }
10141                 }
10142                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10143                     mLastAddedTaskActivity = null;
10144                 }
10145                 ActivityInfo ainfo = mLastAddedTaskActivity;
10146                 if (ainfo == null) {
10147                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10148                             comp, 0, UserHandle.getUserId(callingUid));
10149                     if (ainfo.applicationInfo.uid != callingUid) {
10150                         throw new SecurityException(
10151                                 "Can't add task for another application: target uid="
10152                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10153                     }
10154                 }
10155
10156                 TaskRecord task = new TaskRecord(this,
10157                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10158                         ainfo, intent, description, new TaskThumbnailInfo());
10159
10160                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10161                 if (trimIdx >= 0) {
10162                     // If this would have caused a trim, then we'll abort because that
10163                     // means it would be added at the end of the list but then just removed.
10164                     return INVALID_TASK_ID;
10165                 }
10166
10167                 final int N = mRecentTasks.size();
10168                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10169                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10170                     tr.removedFromRecents();
10171                 }
10172
10173                 task.inRecents = true;
10174                 mRecentTasks.add(task);
10175                 r.getStack().addTask(task, false, "addAppTask");
10176
10177                 task.setLastThumbnailLocked(thumbnail);
10178                 task.freeLastThumbnail();
10179                 return task.taskId;
10180             }
10181         } finally {
10182             Binder.restoreCallingIdentity(callingIdent);
10183         }
10184     }
10185
10186     @Override
10187     public Point getAppTaskThumbnailSize() {
10188         synchronized (this) {
10189             return new Point(mThumbnailWidth,  mThumbnailHeight);
10190         }
10191     }
10192
10193     @Override
10194     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10195         synchronized (this) {
10196             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10197             if (r != null) {
10198                 r.setTaskDescription(td);
10199                 final TaskRecord task = r.getTask();
10200                 task.updateTaskDescription();
10201                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10202             }
10203         }
10204     }
10205
10206     @Override
10207     public void setTaskResizeable(int taskId, int resizeableMode) {
10208         synchronized (this) {
10209             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10210                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10211             if (task == null) {
10212                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10213                 return;
10214             }
10215             task.setResizeMode(resizeableMode);
10216         }
10217     }
10218
10219     @Override
10220     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10221         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10222         long ident = Binder.clearCallingIdentity();
10223         try {
10224             synchronized (this) {
10225                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10226                 if (task == null) {
10227                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10228                     return;
10229                 }
10230                 // Place the task in the right stack if it isn't there already based on
10231                 // the requested bounds.
10232                 // The stack transition logic is:
10233                 // - a null bounds on a freeform task moves that task to fullscreen
10234                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10235                 //   that task to freeform
10236                 // - otherwise the task is not moved
10237                 int stackId = task.getStackId();
10238                 if (!StackId.isTaskResizeAllowed(stackId)) {
10239                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10240                 }
10241                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10242                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10243                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10244                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10245                 }
10246
10247                 // Reparent the task to the right stack if necessary
10248                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10249                 if (stackId != task.getStackId()) {
10250                     // Defer resume until the task is resized below
10251                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10252                             DEFER_RESUME, "resizeTask");
10253                     preserveWindow = false;
10254                 }
10255
10256                 // After reparenting (which only resizes the task to the stack bounds), resize the
10257                 // task to the actual bounds provided
10258                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10259             }
10260         } finally {
10261             Binder.restoreCallingIdentity(ident);
10262         }
10263     }
10264
10265     @Override
10266     public Rect getTaskBounds(int taskId) {
10267         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10268         long ident = Binder.clearCallingIdentity();
10269         Rect rect = new Rect();
10270         try {
10271             synchronized (this) {
10272                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10273                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10274                 if (task == null) {
10275                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10276                     return rect;
10277                 }
10278                 if (task.getStack() != null) {
10279                     // Return the bounds from window manager since it will be adjusted for various
10280                     // things like the presense of a docked stack for tasks that aren't resizeable.
10281                     task.getWindowContainerBounds(rect);
10282                 } else {
10283                     // Task isn't in window manager yet since it isn't associated with a stack.
10284                     // Return the persist value from activity manager
10285                     if (task.mBounds != null) {
10286                         rect.set(task.mBounds);
10287                     } else if (task.mLastNonFullscreenBounds != null) {
10288                         rect.set(task.mLastNonFullscreenBounds);
10289                     }
10290                 }
10291             }
10292         } finally {
10293             Binder.restoreCallingIdentity(ident);
10294         }
10295         return rect;
10296     }
10297
10298     @Override
10299     public void cancelTaskWindowTransition(int taskId) {
10300         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10301         final long ident = Binder.clearCallingIdentity();
10302         try {
10303             synchronized (this) {
10304                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10305                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10306                 if (task == null) {
10307                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10308                     return;
10309                 }
10310                 task.cancelWindowTransition();
10311             }
10312         } finally {
10313             Binder.restoreCallingIdentity(ident);
10314         }
10315     }
10316
10317     @Override
10318     public void cancelTaskThumbnailTransition(int taskId) {
10319         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10320         final long ident = Binder.clearCallingIdentity();
10321         try {
10322             synchronized (this) {
10323                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10324                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10325                 if (task == null) {
10326                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10327                     return;
10328                 }
10329                 task.cancelThumbnailTransition();
10330             }
10331         } finally {
10332             Binder.restoreCallingIdentity(ident);
10333         }
10334     }
10335
10336     @Override
10337     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10338         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10339         final long ident = Binder.clearCallingIdentity();
10340         try {
10341             final TaskRecord task;
10342             synchronized (this) {
10343                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10344                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10345                 if (task == null) {
10346                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10347                     return null;
10348                 }
10349             }
10350             // Don't call this while holding the lock as this operation might hit the disk.
10351             return task.getSnapshot(reducedResolution);
10352         } finally {
10353             Binder.restoreCallingIdentity(ident);
10354         }
10355     }
10356
10357     @Override
10358     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10359         if (userId != UserHandle.getCallingUserId()) {
10360             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10361                     "getTaskDescriptionIcon");
10362         }
10363         final File passedIconFile = new File(filePath);
10364         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10365                 passedIconFile.getName());
10366         if (!legitIconFile.getPath().equals(filePath)
10367                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10368             throw new IllegalArgumentException("Bad file path: " + filePath
10369                     + " passed for userId " + userId);
10370         }
10371         return mRecentTasks.getTaskDescriptionIcon(filePath);
10372     }
10373
10374     @Override
10375     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10376             throws RemoteException {
10377         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10378         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10379                 activityOptions.getCustomInPlaceResId() == 0) {
10380             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10381                     "with valid animation");
10382         }
10383         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10384         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10385                 activityOptions.getCustomInPlaceResId());
10386         mWindowManager.executeAppTransition();
10387     }
10388
10389     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10390         // Remove all tasks with activities in the specified package from the list of recent tasks
10391         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10392             TaskRecord tr = mRecentTasks.get(i);
10393             if (tr.userId != userId) continue;
10394
10395             ComponentName cn = tr.intent.getComponent();
10396             if (cn != null && cn.getPackageName().equals(packageName)) {
10397                 // If the package name matches, remove the task.
10398                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10399             }
10400         }
10401     }
10402
10403     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10404             int userId) {
10405
10406         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10407             TaskRecord tr = mRecentTasks.get(i);
10408             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10409                 continue;
10410             }
10411
10412             ComponentName cn = tr.intent.getComponent();
10413             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10414                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10415             if (sameComponent) {
10416                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10417             }
10418         }
10419     }
10420
10421     @Override
10422     public void removeStack(int stackId) {
10423         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10424         if (StackId.isHomeOrRecentsStack(stackId)) {
10425             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10426         }
10427
10428         synchronized (this) {
10429             final long ident = Binder.clearCallingIdentity();
10430             try {
10431                 mStackSupervisor.removeStackLocked(stackId);
10432             } finally {
10433                 Binder.restoreCallingIdentity(ident);
10434             }
10435         }
10436     }
10437
10438     @Override
10439     public void moveStackToDisplay(int stackId, int displayId) {
10440         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10441
10442         synchronized (this) {
10443             final long ident = Binder.clearCallingIdentity();
10444             try {
10445                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10446                         + " to displayId=" + displayId);
10447                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10448             } finally {
10449                 Binder.restoreCallingIdentity(ident);
10450             }
10451         }
10452     }
10453
10454     @Override
10455     public boolean removeTask(int taskId) {
10456         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10457         synchronized (this) {
10458             final long ident = Binder.clearCallingIdentity();
10459             try {
10460                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10461             } finally {
10462                 Binder.restoreCallingIdentity(ident);
10463             }
10464         }
10465     }
10466
10467     /**
10468      * TODO: Add mController hook
10469      */
10470     @Override
10471     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10472         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10473
10474         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10475         synchronized(this) {
10476             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10477         }
10478     }
10479
10480     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10481         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10482
10483         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10484                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10485             ActivityOptions.abort(options);
10486             return;
10487         }
10488         final long origId = Binder.clearCallingIdentity();
10489         try {
10490             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10491             if (task == null) {
10492                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10493                 return;
10494             }
10495             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10496                 mStackSupervisor.showLockTaskToast();
10497                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10498                 return;
10499             }
10500             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10501             if (prev != null) {
10502                 task.setTaskToReturnTo(prev);
10503             }
10504             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10505                     false /* forceNonResizable */);
10506
10507             final ActivityRecord topActivity = task.getTopActivity();
10508             if (topActivity != null) {
10509
10510                 // We are reshowing a task, use a starting window to hide the initial draw delay
10511                 // so the transition can start earlier.
10512                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10513                         true /* taskSwitch */, fromRecents);
10514             }
10515         } finally {
10516             Binder.restoreCallingIdentity(origId);
10517         }
10518         ActivityOptions.abort(options);
10519     }
10520
10521     /**
10522      * Attempts to move a task backwards in z-order (the order of activities within the task is
10523      * unchanged).
10524      *
10525      * There are several possible results of this call:
10526      * - if the task is locked, then we will show the lock toast
10527      * - if there is a task behind the provided task, then that task is made visible and resumed as
10528      *   this task is moved to the back
10529      * - otherwise, if there are no other tasks in the stack:
10530      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10531      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10532      *       (depending on whether it is visible)
10533      *     - otherwise, we simply return home and hide this task
10534      *
10535      * @param token A reference to the activity we wish to move
10536      * @param nonRoot If false then this only works if the activity is the root
10537      *                of a task; if true it will work for any activity in a task.
10538      * @return Returns true if the move completed, false if not.
10539      */
10540     @Override
10541     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10542         enforceNotIsolatedCaller("moveActivityTaskToBack");
10543         synchronized(this) {
10544             final long origId = Binder.clearCallingIdentity();
10545             try {
10546                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10547                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10548                 if (task != null) {
10549                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10550                 }
10551             } finally {
10552                 Binder.restoreCallingIdentity(origId);
10553             }
10554         }
10555         return false;
10556     }
10557
10558     @Override
10559     public void moveTaskBackwards(int task) {
10560         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10561                 "moveTaskBackwards()");
10562
10563         synchronized(this) {
10564             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10565                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10566                 return;
10567             }
10568             final long origId = Binder.clearCallingIdentity();
10569             moveTaskBackwardsLocked(task);
10570             Binder.restoreCallingIdentity(origId);
10571         }
10572     }
10573
10574     private final void moveTaskBackwardsLocked(int task) {
10575         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10576     }
10577
10578     @Override
10579     public int createStackOnDisplay(int displayId) throws RemoteException {
10580         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10581         synchronized (this) {
10582             final int stackId = mStackSupervisor.getNextStackId();
10583             final ActivityStack stack =
10584                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10585             if (stack == null) {
10586                 return INVALID_STACK_ID;
10587             }
10588             return stack.mStackId;
10589         }
10590     }
10591
10592     @Override
10593     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10594         synchronized (this) {
10595             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10596             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10597                 return stack.mDisplayId;
10598             }
10599             return DEFAULT_DISPLAY;
10600         }
10601     }
10602
10603     @Override
10604     public int getActivityStackId(IBinder token) throws RemoteException {
10605         synchronized (this) {
10606             ActivityStack stack = ActivityRecord.getStackLocked(token);
10607             if (stack == null) {
10608                 return INVALID_STACK_ID;
10609             }
10610             return stack.mStackId;
10611         }
10612     }
10613
10614     @Override
10615     public void exitFreeformMode(IBinder token) throws RemoteException {
10616         synchronized (this) {
10617             long ident = Binder.clearCallingIdentity();
10618             try {
10619                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10620                 if (r == null) {
10621                     throw new IllegalArgumentException(
10622                             "exitFreeformMode: No activity record matching token=" + token);
10623                 }
10624
10625                 final ActivityStack stack = r.getStack();
10626                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10627                     throw new IllegalStateException(
10628                             "exitFreeformMode: You can only go fullscreen from freeform.");
10629                 }
10630
10631                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10632                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10633                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10634             } finally {
10635                 Binder.restoreCallingIdentity(ident);
10636             }
10637         }
10638     }
10639
10640     @Override
10641     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10642         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10643         if (StackId.isHomeOrRecentsStack(stackId)) {
10644             throw new IllegalArgumentException(
10645                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10646         }
10647         synchronized (this) {
10648             long ident = Binder.clearCallingIdentity();
10649             try {
10650                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10651                 if (task == null) {
10652                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10653                     return;
10654                 }
10655
10656                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10657                         + " to stackId=" + stackId + " toTop=" + toTop);
10658                 if (stackId == DOCKED_STACK_ID) {
10659                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10660                             null /* initialBounds */);
10661                 }
10662                 task.reparent(stackId, toTop,
10663                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10664             } finally {
10665                 Binder.restoreCallingIdentity(ident);
10666             }
10667         }
10668     }
10669
10670     @Override
10671     public void swapDockedAndFullscreenStack() throws RemoteException {
10672         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10673         synchronized (this) {
10674             long ident = Binder.clearCallingIdentity();
10675             try {
10676                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10677                         FULLSCREEN_WORKSPACE_STACK_ID);
10678                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10679                         : null;
10680                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10681                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10682                         : null;
10683                 if (topTask == null || tasks == null || tasks.size() == 0) {
10684                     Slog.w(TAG,
10685                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10686                     return;
10687                 }
10688
10689                 // TODO: App transition
10690                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10691
10692                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10693                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10694                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10695                 final int size = tasks.size();
10696                 for (int i = 0; i < size; i++) {
10697                     final int id = tasks.get(i).taskId;
10698                     if (id == topTask.taskId) {
10699                         continue;
10700                     }
10701
10702                     // Defer the resume until after all the tasks have been moved
10703                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10704                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10705                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10706                 }
10707
10708                 // Because we deferred the resume to avoid conflicts with stack switches while
10709                 // resuming, we need to do it after all the tasks are moved.
10710                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10711                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10712
10713                 mWindowManager.executeAppTransition();
10714             } finally {
10715                 Binder.restoreCallingIdentity(ident);
10716             }
10717         }
10718     }
10719
10720     /**
10721      * Moves the input task to the docked stack.
10722      *
10723      * @param taskId Id of task to move.
10724      * @param createMode The mode the docked stack should be created in if it doesn't exist
10725      *                   already. See
10726      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10727      *                   and
10728      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10729      * @param toTop If the task and stack should be moved to the top.
10730      * @param animate Whether we should play an animation for the moving the task
10731      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10732      *                      docked stack. Pass {@code null} to use default bounds.
10733      */
10734     @Override
10735     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10736             Rect initialBounds) {
10737         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10738         synchronized (this) {
10739             long ident = Binder.clearCallingIdentity();
10740             try {
10741                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10742                 if (task == null) {
10743                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10744                     return false;
10745                 }
10746
10747                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10748                         + " to createMode=" + createMode + " toTop=" + toTop);
10749                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10750
10751                 // Defer resuming until we move the home stack to the front below
10752                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10753                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10754                         "moveTaskToDockedStack");
10755                 if (moved) {
10756                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10757                 }
10758                 return moved;
10759             } finally {
10760                 Binder.restoreCallingIdentity(ident);
10761             }
10762         }
10763     }
10764
10765     /**
10766      * Moves the top activity in the input stackId to the pinned stack.
10767      *
10768      * @param stackId Id of stack to move the top activity to pinned stack.
10769      * @param bounds Bounds to use for pinned stack.
10770      *
10771      * @return True if the top activity of the input stack was successfully moved to the pinned
10772      *          stack.
10773      */
10774     @Override
10775     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10776         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10777         synchronized (this) {
10778             if (!mSupportsPictureInPicture) {
10779                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10780                         + "Device doesn't support picture-in-picture mode");
10781             }
10782
10783             long ident = Binder.clearCallingIdentity();
10784             try {
10785                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10786             } finally {
10787                 Binder.restoreCallingIdentity(ident);
10788             }
10789         }
10790     }
10791
10792     @Override
10793     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10794             boolean preserveWindows, boolean animate, int animationDuration) {
10795         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10796         long ident = Binder.clearCallingIdentity();
10797         try {
10798             synchronized (this) {
10799                 if (animate) {
10800                     if (stackId == PINNED_STACK_ID) {
10801                         final PinnedActivityStack pinnedStack =
10802                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10803                         if (pinnedStack != null) {
10804                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10805                                     destBounds, animationDuration, false /* fromFullscreen */);
10806                         }
10807                     } else {
10808                         throw new IllegalArgumentException("Stack: " + stackId
10809                                 + " doesn't support animated resize.");
10810                     }
10811                 } else {
10812                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10813                             null /* tempTaskInsetBounds */, preserveWindows,
10814                             allowResizeInDockedMode, !DEFER_RESUME);
10815                 }
10816             }
10817         } finally {
10818             Binder.restoreCallingIdentity(ident);
10819         }
10820     }
10821
10822     @Override
10823     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10824             Rect tempDockedTaskInsetBounds,
10825             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10826         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10827                 "resizeDockedStack()");
10828         long ident = Binder.clearCallingIdentity();
10829         try {
10830             synchronized (this) {
10831                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10832                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10833                         PRESERVE_WINDOWS);
10834             }
10835         } finally {
10836             Binder.restoreCallingIdentity(ident);
10837         }
10838     }
10839
10840     @Override
10841     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10842         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10843                 "resizePinnedStack()");
10844         final long ident = Binder.clearCallingIdentity();
10845         try {
10846             synchronized (this) {
10847                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10848             }
10849         } finally {
10850             Binder.restoreCallingIdentity(ident);
10851         }
10852     }
10853
10854     /**
10855      * Try to place task to provided position. The final position might be different depending on
10856      * current user and stacks state. The task will be moved to target stack if it's currently in
10857      * different stack.
10858      */
10859     @Override
10860     public void positionTaskInStack(int taskId, int stackId, int position) {
10861         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10862         if (StackId.isHomeOrRecentsStack(stackId)) {
10863             throw new IllegalArgumentException(
10864                     "positionTaskInStack: Attempt to change the position of task "
10865                     + taskId + " in/to home/recents stack");
10866         }
10867         synchronized (this) {
10868             long ident = Binder.clearCallingIdentity();
10869             try {
10870                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10871                         + taskId + " in stackId=" + stackId + " at position=" + position);
10872                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10873                 if (task == null) {
10874                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10875                             + taskId);
10876                 }
10877
10878                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10879                         !ON_TOP);
10880
10881                 // TODO: Have the callers of this API call a separate reparent method if that is
10882                 // what they intended to do vs. having this method also do reparenting.
10883                 if (task.getStack() == stack) {
10884                     // Change position in current stack.
10885                     stack.positionChildAt(task, position);
10886                 } else {
10887                     // Reparent to new stack.
10888                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10889                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10890                 }
10891             } finally {
10892                 Binder.restoreCallingIdentity(ident);
10893             }
10894         }
10895     }
10896
10897     @Override
10898     public List<StackInfo> getAllStackInfos() {
10899         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10900         long ident = Binder.clearCallingIdentity();
10901         try {
10902             synchronized (this) {
10903                 return mStackSupervisor.getAllStackInfosLocked();
10904             }
10905         } finally {
10906             Binder.restoreCallingIdentity(ident);
10907         }
10908     }
10909
10910     @Override
10911     public StackInfo getStackInfo(int stackId) {
10912         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10913         long ident = Binder.clearCallingIdentity();
10914         try {
10915             synchronized (this) {
10916                 return mStackSupervisor.getStackInfoLocked(stackId);
10917             }
10918         } finally {
10919             Binder.restoreCallingIdentity(ident);
10920         }
10921     }
10922
10923     @Override
10924     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10925         synchronized(this) {
10926             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10927         }
10928     }
10929
10930     @Override
10931     public void updateDeviceOwner(String packageName) {
10932         final int callingUid = Binder.getCallingUid();
10933         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10934             throw new SecurityException("updateDeviceOwner called from non-system process");
10935         }
10936         synchronized (this) {
10937             mDeviceOwnerName = packageName;
10938         }
10939     }
10940
10941     @Override
10942     public void updateLockTaskPackages(int userId, String[] packages) {
10943         final int callingUid = Binder.getCallingUid();
10944         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10945             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10946                     "updateLockTaskPackages()");
10947         }
10948         synchronized (this) {
10949             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10950                     Arrays.toString(packages));
10951             mLockTaskPackages.put(userId, packages);
10952             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10953         }
10954     }
10955
10956
10957     void startLockTaskModeLocked(TaskRecord task) {
10958         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10959         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10960             return;
10961         }
10962
10963         // When a task is locked, dismiss the pinned stack if it exists
10964         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10965                 PINNED_STACK_ID);
10966         if (pinnedStack != null) {
10967             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10968         }
10969
10970         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10971         // is initiated by system after the pinning request was shown and locked mode is initiated
10972         // by an authorized app directly
10973         final int callingUid = Binder.getCallingUid();
10974         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10975         long ident = Binder.clearCallingIdentity();
10976         try {
10977             if (!isSystemInitiated) {
10978                 task.mLockTaskUid = callingUid;
10979                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10980                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10981                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10982                     StatusBarManagerInternal statusBarManager =
10983                             LocalServices.getService(StatusBarManagerInternal.class);
10984                     if (statusBarManager != null) {
10985                         statusBarManager.showScreenPinningRequest(task.taskId);
10986                     }
10987                     return;
10988                 }
10989
10990                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10991                 if (stack == null || task != stack.topTask()) {
10992                     throw new IllegalArgumentException("Invalid task, not in foreground");
10993                 }
10994             }
10995             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10996                     "Locking fully");
10997             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10998                     ActivityManager.LOCK_TASK_MODE_PINNED :
10999                     ActivityManager.LOCK_TASK_MODE_LOCKED,
11000                     "startLockTask", true);
11001         } finally {
11002             Binder.restoreCallingIdentity(ident);
11003         }
11004     }
11005
11006     @Override
11007     public void startLockTaskModeById(int taskId) {
11008         synchronized (this) {
11009             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
11010             if (task != null) {
11011                 startLockTaskModeLocked(task);
11012             }
11013         }
11014     }
11015
11016     @Override
11017     public void startLockTaskModeByToken(IBinder token) {
11018         synchronized (this) {
11019             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11020             if (r == null) {
11021                 return;
11022             }
11023             final TaskRecord task = r.getTask();
11024             if (task != null) {
11025                 startLockTaskModeLocked(task);
11026             }
11027         }
11028     }
11029
11030     @Override
11031     public void startSystemLockTaskMode(int taskId) throws RemoteException {
11032         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11033         // This makes inner call to look as if it was initiated by system.
11034         long ident = Binder.clearCallingIdentity();
11035         try {
11036             synchronized (this) {
11037                 startLockTaskModeById(taskId);
11038             }
11039         } finally {
11040             Binder.restoreCallingIdentity(ident);
11041         }
11042     }
11043
11044     @Override
11045     public void stopLockTaskMode() {
11046         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11047         if (lockTask == null) {
11048             // Our work here is done.
11049             return;
11050         }
11051
11052         final int callingUid = Binder.getCallingUid();
11053         final int lockTaskUid = lockTask.mLockTaskUid;
11054         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11055         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11056             // Done.
11057             return;
11058         } else {
11059             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11060             // It is possible lockTaskMode was started by the system process because
11061             // android:lockTaskMode is set to a locking value in the application manifest
11062             // instead of the app calling startLockTaskMode. In this case
11063             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11064             // {@link TaskRecord.effectiveUid} instead. Also caller with
11065             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11066             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11067                     && callingUid != lockTaskUid
11068                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11069                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11070                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11071             }
11072         }
11073         long ident = Binder.clearCallingIdentity();
11074         try {
11075             Log.d(TAG, "stopLockTaskMode");
11076             // Stop lock task
11077             synchronized (this) {
11078                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11079                         "stopLockTask", true);
11080             }
11081             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11082             if (tm != null) {
11083                 tm.showInCallScreen(false);
11084             }
11085         } finally {
11086             Binder.restoreCallingIdentity(ident);
11087         }
11088     }
11089
11090     /**
11091      * This API should be called by SystemUI only when user perform certain action to dismiss
11092      * lock task mode. We should only dismiss pinned lock task mode in this case.
11093      */
11094     @Override
11095     public void stopSystemLockTaskMode() throws RemoteException {
11096         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11097             stopLockTaskMode();
11098         } else {
11099             mStackSupervisor.showLockTaskToast();
11100         }
11101     }
11102
11103     @Override
11104     public boolean isInLockTaskMode() {
11105         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11106     }
11107
11108     @Override
11109     public int getLockTaskModeState() {
11110         synchronized (this) {
11111             return mStackSupervisor.getLockTaskModeState();
11112         }
11113     }
11114
11115     @Override
11116     public void showLockTaskEscapeMessage(IBinder token) {
11117         synchronized (this) {
11118             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11119             if (r == null) {
11120                 return;
11121             }
11122             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11123         }
11124     }
11125
11126     @Override
11127     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11128             throws RemoteException {
11129         synchronized (this) {
11130             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11131             if (r == null) {
11132                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11133                         + token);
11134                 return;
11135             }
11136             final long origId = Binder.clearCallingIdentity();
11137             try {
11138                 r.setDisablePreviewScreenshots(disable);
11139             } finally {
11140                 Binder.restoreCallingIdentity(origId);
11141             }
11142         }
11143     }
11144
11145     // =========================================================
11146     // CONTENT PROVIDERS
11147     // =========================================================
11148
11149     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11150         List<ProviderInfo> providers = null;
11151         try {
11152             providers = AppGlobals.getPackageManager()
11153                     .queryContentProviders(app.processName, app.uid,
11154                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11155                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11156                     .getList();
11157         } catch (RemoteException ex) {
11158         }
11159         if (DEBUG_MU) Slog.v(TAG_MU,
11160                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11161         int userId = app.userId;
11162         if (providers != null) {
11163             int N = providers.size();
11164             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11165             for (int i=0; i<N; i++) {
11166                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11167                 ProviderInfo cpi =
11168                     (ProviderInfo)providers.get(i);
11169                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11170                         cpi.name, cpi.flags);
11171                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11172                     // This is a singleton provider, but a user besides the
11173                     // default user is asking to initialize a process it runs
11174                     // in...  well, no, it doesn't actually run in this process,
11175                     // it runs in the process of the default user.  Get rid of it.
11176                     providers.remove(i);
11177                     N--;
11178                     i--;
11179                     continue;
11180                 }
11181
11182                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11183                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11184                 if (cpr == null) {
11185                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11186                     mProviderMap.putProviderByClass(comp, cpr);
11187                 }
11188                 if (DEBUG_MU) Slog.v(TAG_MU,
11189                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11190                 app.pubProviders.put(cpi.name, cpr);
11191                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11192                     // Don't add this if it is a platform component that is marked
11193                     // to run in multiple processes, because this is actually
11194                     // part of the framework so doesn't make sense to track as a
11195                     // separate apk in the process.
11196                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11197                             mProcessStats);
11198                 }
11199                 notifyPackageUse(cpi.applicationInfo.packageName,
11200                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11201             }
11202         }
11203         return providers;
11204     }
11205
11206     /**
11207      * Check if the calling UID has a possible chance at accessing the provider
11208      * at the given authority and user.
11209      */
11210     public String checkContentProviderAccess(String authority, int userId) {
11211         if (userId == UserHandle.USER_ALL) {
11212             mContext.enforceCallingOrSelfPermission(
11213                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11214             userId = UserHandle.getCallingUserId();
11215         }
11216
11217         ProviderInfo cpi = null;
11218         try {
11219             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11220                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11221                             | PackageManager.MATCH_DISABLED_COMPONENTS
11222                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11223                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11224                     userId);
11225         } catch (RemoteException ignored) {
11226         }
11227         if (cpi == null) {
11228             return "Failed to find provider " + authority + " for user " + userId
11229                     + "; expected to find a valid ContentProvider for this authority";
11230         }
11231
11232         ProcessRecord r = null;
11233         synchronized (mPidsSelfLocked) {
11234             r = mPidsSelfLocked.get(Binder.getCallingPid());
11235         }
11236         if (r == null) {
11237             return "Failed to find PID " + Binder.getCallingPid();
11238         }
11239
11240         synchronized (this) {
11241             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11242         }
11243     }
11244
11245     /**
11246      * Check if {@link ProcessRecord} has a possible chance at accessing the
11247      * given {@link ProviderInfo}. Final permission checking is always done
11248      * in {@link ContentProvider}.
11249      */
11250     private final String checkContentProviderPermissionLocked(
11251             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11252         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11253         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11254         boolean checkedGrants = false;
11255         if (checkUser) {
11256             // Looking for cross-user grants before enforcing the typical cross-users permissions
11257             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11258             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11259                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11260                     return null;
11261                 }
11262                 checkedGrants = true;
11263             }
11264             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11265                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11266             if (userId != tmpTargetUserId) {
11267                 // When we actually went to determine the final targer user ID, this ended
11268                 // up different than our initial check for the authority.  This is because
11269                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11270                 // SELF.  So we need to re-check the grants again.
11271                 checkedGrants = false;
11272             }
11273         }
11274         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11275                 cpi.applicationInfo.uid, cpi.exported)
11276                 == PackageManager.PERMISSION_GRANTED) {
11277             return null;
11278         }
11279         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11280                 cpi.applicationInfo.uid, cpi.exported)
11281                 == PackageManager.PERMISSION_GRANTED) {
11282             return null;
11283         }
11284
11285         PathPermission[] pps = cpi.pathPermissions;
11286         if (pps != null) {
11287             int i = pps.length;
11288             while (i > 0) {
11289                 i--;
11290                 PathPermission pp = pps[i];
11291                 String pprperm = pp.getReadPermission();
11292                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11293                         cpi.applicationInfo.uid, cpi.exported)
11294                         == PackageManager.PERMISSION_GRANTED) {
11295                     return null;
11296                 }
11297                 String ppwperm = pp.getWritePermission();
11298                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11299                         cpi.applicationInfo.uid, cpi.exported)
11300                         == PackageManager.PERMISSION_GRANTED) {
11301                     return null;
11302                 }
11303             }
11304         }
11305         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11306             return null;
11307         }
11308
11309         final String suffix;
11310         if (!cpi.exported) {
11311             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11312         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11313             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11314         } else {
11315             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11316         }
11317         final String msg = "Permission Denial: opening provider " + cpi.name
11318                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11319                 + ", uid=" + callingUid + ")" + suffix;
11320         Slog.w(TAG, msg);
11321         return msg;
11322     }
11323
11324     /**
11325      * Returns if the ContentProvider has granted a uri to callingUid
11326      */
11327     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11328         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11329         if (perms != null) {
11330             for (int i=perms.size()-1; i>=0; i--) {
11331                 GrantUri grantUri = perms.keyAt(i);
11332                 if (grantUri.sourceUserId == userId || !checkUser) {
11333                     if (matchesProvider(grantUri.uri, cpi)) {
11334                         return true;
11335                     }
11336                 }
11337             }
11338         }
11339         return false;
11340     }
11341
11342     /**
11343      * Returns true if the uri authority is one of the authorities specified in the provider.
11344      */
11345     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11346         String uriAuth = uri.getAuthority();
11347         String cpiAuth = cpi.authority;
11348         if (cpiAuth.indexOf(';') == -1) {
11349             return cpiAuth.equals(uriAuth);
11350         }
11351         String[] cpiAuths = cpiAuth.split(";");
11352         int length = cpiAuths.length;
11353         for (int i = 0; i < length; i++) {
11354             if (cpiAuths[i].equals(uriAuth)) return true;
11355         }
11356         return false;
11357     }
11358
11359     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11360             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11361         if (r != null) {
11362             for (int i=0; i<r.conProviders.size(); i++) {
11363                 ContentProviderConnection conn = r.conProviders.get(i);
11364                 if (conn.provider == cpr) {
11365                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11366                             "Adding provider requested by "
11367                             + r.processName + " from process "
11368                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11369                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11370                     if (stable) {
11371                         conn.stableCount++;
11372                         conn.numStableIncs++;
11373                     } else {
11374                         conn.unstableCount++;
11375                         conn.numUnstableIncs++;
11376                     }
11377                     return conn;
11378                 }
11379             }
11380             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11381             if (stable) {
11382                 conn.stableCount = 1;
11383                 conn.numStableIncs = 1;
11384             } else {
11385                 conn.unstableCount = 1;
11386                 conn.numUnstableIncs = 1;
11387             }
11388             cpr.connections.add(conn);
11389             r.conProviders.add(conn);
11390             startAssociationLocked(r.uid, r.processName, r.curProcState,
11391                     cpr.uid, cpr.name, cpr.info.processName);
11392             return conn;
11393         }
11394         cpr.addExternalProcessHandleLocked(externalProcessToken);
11395         return null;
11396     }
11397
11398     boolean decProviderCountLocked(ContentProviderConnection conn,
11399             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11400         if (conn != null) {
11401             cpr = conn.provider;
11402             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11403                     "Removing provider requested by "
11404                     + conn.client.processName + " from process "
11405                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11406                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11407             if (stable) {
11408                 conn.stableCount--;
11409             } else {
11410                 conn.unstableCount--;
11411             }
11412             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11413                 cpr.connections.remove(conn);
11414                 conn.client.conProviders.remove(conn);
11415                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11416                     // The client is more important than last activity -- note the time this
11417                     // is happening, so we keep the old provider process around a bit as last
11418                     // activity to avoid thrashing it.
11419                     if (cpr.proc != null) {
11420                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11421                     }
11422                 }
11423                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11424                 return true;
11425             }
11426             return false;
11427         }
11428         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11429         return false;
11430     }
11431
11432     private void checkTime(long startTime, String where) {
11433         long now = SystemClock.uptimeMillis();
11434         if ((now-startTime) > 50) {
11435             // If we are taking more than 50ms, log about it.
11436             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11437         }
11438     }
11439
11440     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11441             PROC_SPACE_TERM,
11442             PROC_SPACE_TERM|PROC_PARENS,
11443             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11444     };
11445
11446     private final long[] mProcessStateStatsLongs = new long[1];
11447
11448     boolean isProcessAliveLocked(ProcessRecord proc) {
11449         if (proc.procStatFile == null) {
11450             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11451         }
11452         mProcessStateStatsLongs[0] = 0;
11453         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11454                 mProcessStateStatsLongs, null)) {
11455             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11456             return false;
11457         }
11458         final long state = mProcessStateStatsLongs[0];
11459         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11460                 + (char)state);
11461         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11462     }
11463
11464     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11465             String name, IBinder token, boolean stable, int userId) {
11466         ContentProviderRecord cpr;
11467         ContentProviderConnection conn = null;
11468         ProviderInfo cpi = null;
11469
11470         synchronized(this) {
11471             long startTime = SystemClock.uptimeMillis();
11472
11473             ProcessRecord r = null;
11474             if (caller != null) {
11475                 r = getRecordForAppLocked(caller);
11476                 if (r == null) {
11477                     throw new SecurityException(
11478                             "Unable to find app for caller " + caller
11479                           + " (pid=" + Binder.getCallingPid()
11480                           + ") when getting content provider " + name);
11481                 }
11482             }
11483
11484             boolean checkCrossUser = true;
11485
11486             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11487
11488             // First check if this content provider has been published...
11489             cpr = mProviderMap.getProviderByName(name, userId);
11490             // If that didn't work, check if it exists for user 0 and then
11491             // verify that it's a singleton provider before using it.
11492             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11493                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11494                 if (cpr != null) {
11495                     cpi = cpr.info;
11496                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11497                             cpi.name, cpi.flags)
11498                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11499                         userId = UserHandle.USER_SYSTEM;
11500                         checkCrossUser = false;
11501                     } else {
11502                         cpr = null;
11503                         cpi = null;
11504                     }
11505                 }
11506             }
11507
11508             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11509             if (providerRunning) {
11510                 cpi = cpr.info;
11511                 String msg;
11512                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11513                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11514                         != null) {
11515                     throw new SecurityException(msg);
11516                 }
11517                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11518
11519                 if (r != null && cpr.canRunHere(r)) {
11520                     // This provider has been published or is in the process
11521                     // of being published...  but it is also allowed to run
11522                     // in the caller's process, so don't make a connection
11523                     // and just let the caller instantiate its own instance.
11524                     ContentProviderHolder holder = cpr.newHolder(null);
11525                     // don't give caller the provider object, it needs
11526                     // to make its own.
11527                     holder.provider = null;
11528                     return holder;
11529                 }
11530                 // Don't expose providers between normal apps and instant apps
11531                 try {
11532                     if (AppGlobals.getPackageManager()
11533                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11534                         return null;
11535                     }
11536                 } catch (RemoteException e) {
11537                 }
11538
11539                 final long origId = Binder.clearCallingIdentity();
11540
11541                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11542
11543                 // In this case the provider instance already exists, so we can
11544                 // return it right away.
11545                 conn = incProviderCountLocked(r, cpr, token, stable);
11546                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11547                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11548                         // If this is a perceptible app accessing the provider,
11549                         // make sure to count it as being accessed and thus
11550                         // back up on the LRU list.  This is good because
11551                         // content providers are often expensive to start.
11552                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11553                         updateLruProcessLocked(cpr.proc, false, null);
11554                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11555                     }
11556                 }
11557
11558                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11559                 final int verifiedAdj = cpr.proc.verifiedAdj;
11560                 boolean success = updateOomAdjLocked(cpr.proc, true);
11561                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11562                 // if the process has been successfully adjusted.  So to reduce races with
11563                 // it, we will check whether the process still exists.  Note that this doesn't
11564                 // completely get rid of races with LMK killing the process, but should make
11565                 // them much smaller.
11566                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11567                     success = false;
11568                 }
11569                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11570                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11571                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11572                 // NOTE: there is still a race here where a signal could be
11573                 // pending on the process even though we managed to update its
11574                 // adj level.  Not sure what to do about this, but at least
11575                 // the race is now smaller.
11576                 if (!success) {
11577                     // Uh oh...  it looks like the provider's process
11578                     // has been killed on us.  We need to wait for a new
11579                     // process to be started, and make sure its death
11580                     // doesn't kill our process.
11581                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11582                             + " is crashing; detaching " + r);
11583                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11584                     checkTime(startTime, "getContentProviderImpl: before appDied");
11585                     appDiedLocked(cpr.proc);
11586                     checkTime(startTime, "getContentProviderImpl: after appDied");
11587                     if (!lastRef) {
11588                         // This wasn't the last ref our process had on
11589                         // the provider...  we have now been killed, bail.
11590                         return null;
11591                     }
11592                     providerRunning = false;
11593                     conn = null;
11594                 } else {
11595                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11596                 }
11597
11598                 Binder.restoreCallingIdentity(origId);
11599             }
11600
11601             if (!providerRunning) {
11602                 try {
11603                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11604                     cpi = AppGlobals.getPackageManager().
11605                         resolveContentProvider(name,
11606                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11607                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11608                 } catch (RemoteException ex) {
11609                 }
11610                 if (cpi == null) {
11611                     return null;
11612                 }
11613                 // If the provider is a singleton AND
11614                 // (it's a call within the same user || the provider is a
11615                 // privileged app)
11616                 // Then allow connecting to the singleton provider
11617                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11618                         cpi.name, cpi.flags)
11619                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11620                 if (singleton) {
11621                     userId = UserHandle.USER_SYSTEM;
11622                 }
11623                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11624                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11625
11626                 String msg;
11627                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11628                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11629                         != null) {
11630                     throw new SecurityException(msg);
11631                 }
11632                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11633
11634                 if (!mProcessesReady
11635                         && !cpi.processName.equals("system")) {
11636                     // If this content provider does not run in the system
11637                     // process, and the system is not yet ready to run other
11638                     // processes, then fail fast instead of hanging.
11639                     throw new IllegalArgumentException(
11640                             "Attempt to launch content provider before system ready");
11641                 }
11642
11643                 // Make sure that the user who owns this provider is running.  If not,
11644                 // we don't want to allow it to run.
11645                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11646                     Slog.w(TAG, "Unable to launch app "
11647                             + cpi.applicationInfo.packageName + "/"
11648                             + cpi.applicationInfo.uid + " for provider "
11649                             + name + ": user " + userId + " is stopped");
11650                     return null;
11651                 }
11652
11653                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11654                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11655                 cpr = mProviderMap.getProviderByClass(comp, userId);
11656                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11657                 final boolean firstClass = cpr == null;
11658                 if (firstClass) {
11659                     final long ident = Binder.clearCallingIdentity();
11660
11661                     // If permissions need a review before any of the app components can run,
11662                     // we return no provider and launch a review activity if the calling app
11663                     // is in the foreground.
11664                     if (mPermissionReviewRequired) {
11665                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11666                             return null;
11667                         }
11668                     }
11669
11670                     try {
11671                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11672                         ApplicationInfo ai =
11673                             AppGlobals.getPackageManager().
11674                                 getApplicationInfo(
11675                                         cpi.applicationInfo.packageName,
11676                                         STOCK_PM_FLAGS, userId);
11677                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11678                         if (ai == null) {
11679                             Slog.w(TAG, "No package info for content provider "
11680                                     + cpi.name);
11681                             return null;
11682                         }
11683                         ai = getAppInfoForUser(ai, userId);
11684                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11685                     } catch (RemoteException ex) {
11686                         // pm is in same process, this will never happen.
11687                     } finally {
11688                         Binder.restoreCallingIdentity(ident);
11689                     }
11690                 }
11691
11692                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11693
11694                 if (r != null && cpr.canRunHere(r)) {
11695                     // If this is a multiprocess provider, then just return its
11696                     // info and allow the caller to instantiate it.  Only do
11697                     // this if the provider is the same user as the caller's
11698                     // process, or can run as root (so can be in any process).
11699                     return cpr.newHolder(null);
11700                 }
11701
11702                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11703                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11704                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11705
11706                 // This is single process, and our app is now connecting to it.
11707                 // See if we are already in the process of launching this
11708                 // provider.
11709                 final int N = mLaunchingProviders.size();
11710                 int i;
11711                 for (i = 0; i < N; i++) {
11712                     if (mLaunchingProviders.get(i) == cpr) {
11713                         break;
11714                     }
11715                 }
11716
11717                 // If the provider is not already being launched, then get it
11718                 // started.
11719                 if (i >= N) {
11720                     final long origId = Binder.clearCallingIdentity();
11721
11722                     try {
11723                         // Content provider is now in use, its package can't be stopped.
11724                         try {
11725                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11726                             AppGlobals.getPackageManager().setPackageStoppedState(
11727                                     cpr.appInfo.packageName, false, userId);
11728                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11729                         } catch (RemoteException e) {
11730                         } catch (IllegalArgumentException e) {
11731                             Slog.w(TAG, "Failed trying to unstop package "
11732                                     + cpr.appInfo.packageName + ": " + e);
11733                         }
11734
11735                         // Use existing process if already started
11736                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11737                         ProcessRecord proc = getProcessRecordLocked(
11738                                 cpi.processName, cpr.appInfo.uid, false);
11739                         if (proc != null && proc.thread != null && !proc.killed) {
11740                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11741                                     "Installing in existing process " + proc);
11742                             if (!proc.pubProviders.containsKey(cpi.name)) {
11743                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11744                                 proc.pubProviders.put(cpi.name, cpr);
11745                                 try {
11746                                     proc.thread.scheduleInstallProvider(cpi);
11747                                 } catch (RemoteException e) {
11748                                 }
11749                             }
11750                         } else {
11751                             checkTime(startTime, "getContentProviderImpl: before start process");
11752                             proc = startProcessLocked(cpi.processName,
11753                                     cpr.appInfo, false, 0, "content provider",
11754                                     new ComponentName(cpi.applicationInfo.packageName,
11755                                             cpi.name), false, false, false);
11756                             checkTime(startTime, "getContentProviderImpl: after start process");
11757                             if (proc == null) {
11758                                 Slog.w(TAG, "Unable to launch app "
11759                                         + cpi.applicationInfo.packageName + "/"
11760                                         + cpi.applicationInfo.uid + " for provider "
11761                                         + name + ": process is bad");
11762                                 return null;
11763                             }
11764                         }
11765                         cpr.launchingApp = proc;
11766                         mLaunchingProviders.add(cpr);
11767                     } finally {
11768                         Binder.restoreCallingIdentity(origId);
11769                     }
11770                 }
11771
11772                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11773
11774                 // Make sure the provider is published (the same provider class
11775                 // may be published under multiple names).
11776                 if (firstClass) {
11777                     mProviderMap.putProviderByClass(comp, cpr);
11778                 }
11779
11780                 mProviderMap.putProviderByName(name, cpr);
11781                 conn = incProviderCountLocked(r, cpr, token, stable);
11782                 if (conn != null) {
11783                     conn.waiting = true;
11784                 }
11785             }
11786             checkTime(startTime, "getContentProviderImpl: done!");
11787
11788             grantEphemeralAccessLocked(userId, null /*intent*/,
11789                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11790         }
11791
11792         // Wait for the provider to be published...
11793         synchronized (cpr) {
11794             while (cpr.provider == null) {
11795                 if (cpr.launchingApp == null) {
11796                     Slog.w(TAG, "Unable to launch app "
11797                             + cpi.applicationInfo.packageName + "/"
11798                             + cpi.applicationInfo.uid + " for provider "
11799                             + name + ": launching app became null");
11800                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11801                             UserHandle.getUserId(cpi.applicationInfo.uid),
11802                             cpi.applicationInfo.packageName,
11803                             cpi.applicationInfo.uid, name);
11804                     return null;
11805                 }
11806                 try {
11807                     if (DEBUG_MU) Slog.v(TAG_MU,
11808                             "Waiting to start provider " + cpr
11809                             + " launchingApp=" + cpr.launchingApp);
11810                     if (conn != null) {
11811                         conn.waiting = true;
11812                     }
11813                     cpr.wait();
11814                 } catch (InterruptedException ex) {
11815                 } finally {
11816                     if (conn != null) {
11817                         conn.waiting = false;
11818                     }
11819                 }
11820             }
11821         }
11822         return cpr != null ? cpr.newHolder(conn) : null;
11823     }
11824
11825     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11826             ProcessRecord r, final int userId) {
11827         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11828                 cpi.packageName, userId)) {
11829
11830             final boolean callerForeground = r == null || r.setSchedGroup
11831                     != ProcessList.SCHED_GROUP_BACKGROUND;
11832
11833             // Show a permission review UI only for starting from a foreground app
11834             if (!callerForeground) {
11835                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11836                         + cpi.packageName + " requires a permissions review");
11837                 return false;
11838             }
11839
11840             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11841             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11842                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11843             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11844
11845             if (DEBUG_PERMISSIONS_REVIEW) {
11846                 Slog.i(TAG, "u" + userId + " Launching permission review "
11847                         + "for package " + cpi.packageName);
11848             }
11849
11850             final UserHandle userHandle = new UserHandle(userId);
11851             mHandler.post(new Runnable() {
11852                 @Override
11853                 public void run() {
11854                     mContext.startActivityAsUser(intent, userHandle);
11855                 }
11856             });
11857
11858             return false;
11859         }
11860
11861         return true;
11862     }
11863
11864     PackageManagerInternal getPackageManagerInternalLocked() {
11865         if (mPackageManagerInt == null) {
11866             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11867         }
11868         return mPackageManagerInt;
11869     }
11870
11871     @Override
11872     public final ContentProviderHolder getContentProvider(
11873             IApplicationThread caller, String name, int userId, boolean stable) {
11874         enforceNotIsolatedCaller("getContentProvider");
11875         if (caller == null) {
11876             String msg = "null IApplicationThread when getting content provider "
11877                     + name;
11878             Slog.w(TAG, msg);
11879             throw new SecurityException(msg);
11880         }
11881         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11882         // with cross-user grant.
11883         return getContentProviderImpl(caller, name, null, stable, userId);
11884     }
11885
11886     public ContentProviderHolder getContentProviderExternal(
11887             String name, int userId, IBinder token) {
11888         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11889             "Do not have permission in call getContentProviderExternal()");
11890         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11891                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11892         return getContentProviderExternalUnchecked(name, token, userId);
11893     }
11894
11895     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11896             IBinder token, int userId) {
11897         return getContentProviderImpl(null, name, token, true, userId);
11898     }
11899
11900     /**
11901      * Drop a content provider from a ProcessRecord's bookkeeping
11902      */
11903     public void removeContentProvider(IBinder connection, boolean stable) {
11904         enforceNotIsolatedCaller("removeContentProvider");
11905         long ident = Binder.clearCallingIdentity();
11906         try {
11907             synchronized (this) {
11908                 ContentProviderConnection conn;
11909                 try {
11910                     conn = (ContentProviderConnection)connection;
11911                 } catch (ClassCastException e) {
11912                     String msg ="removeContentProvider: " + connection
11913                             + " not a ContentProviderConnection";
11914                     Slog.w(TAG, msg);
11915                     throw new IllegalArgumentException(msg);
11916                 }
11917                 if (conn == null) {
11918                     throw new NullPointerException("connection is null");
11919                 }
11920                 if (decProviderCountLocked(conn, null, null, stable)) {
11921                     updateOomAdjLocked();
11922                 }
11923             }
11924         } finally {
11925             Binder.restoreCallingIdentity(ident);
11926         }
11927     }
11928
11929     public void removeContentProviderExternal(String name, IBinder token) {
11930         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11931             "Do not have permission in call removeContentProviderExternal()");
11932         int userId = UserHandle.getCallingUserId();
11933         long ident = Binder.clearCallingIdentity();
11934         try {
11935             removeContentProviderExternalUnchecked(name, token, userId);
11936         } finally {
11937             Binder.restoreCallingIdentity(ident);
11938         }
11939     }
11940
11941     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11942         synchronized (this) {
11943             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11944             if(cpr == null) {
11945                 //remove from mProvidersByClass
11946                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11947                 return;
11948             }
11949
11950             //update content provider record entry info
11951             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11952             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11953             if (localCpr.hasExternalProcessHandles()) {
11954                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11955                     updateOomAdjLocked();
11956                 } else {
11957                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11958                             + " with no external reference for token: "
11959                             + token + ".");
11960                 }
11961             } else {
11962                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11963                         + " with no external references.");
11964             }
11965         }
11966     }
11967
11968     public final void publishContentProviders(IApplicationThread caller,
11969             List<ContentProviderHolder> providers) {
11970         if (providers == null) {
11971             return;
11972         }
11973
11974         enforceNotIsolatedCaller("publishContentProviders");
11975         synchronized (this) {
11976             final ProcessRecord r = getRecordForAppLocked(caller);
11977             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11978             if (r == null) {
11979                 throw new SecurityException(
11980                         "Unable to find app for caller " + caller
11981                       + " (pid=" + Binder.getCallingPid()
11982                       + ") when publishing content providers");
11983             }
11984
11985             final long origId = Binder.clearCallingIdentity();
11986
11987             final int N = providers.size();
11988             for (int i = 0; i < N; i++) {
11989                 ContentProviderHolder src = providers.get(i);
11990                 if (src == null || src.info == null || src.provider == null) {
11991                     continue;
11992                 }
11993                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11994                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11995                 if (dst != null) {
11996                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11997                     mProviderMap.putProviderByClass(comp, dst);
11998                     String names[] = dst.info.authority.split(";");
11999                     for (int j = 0; j < names.length; j++) {
12000                         mProviderMap.putProviderByName(names[j], dst);
12001                     }
12002
12003                     int launchingCount = mLaunchingProviders.size();
12004                     int j;
12005                     boolean wasInLaunchingProviders = false;
12006                     for (j = 0; j < launchingCount; j++) {
12007                         if (mLaunchingProviders.get(j) == dst) {
12008                             mLaunchingProviders.remove(j);
12009                             wasInLaunchingProviders = true;
12010                             j--;
12011                             launchingCount--;
12012                         }
12013                     }
12014                     if (wasInLaunchingProviders) {
12015                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12016                     }
12017                     synchronized (dst) {
12018                         dst.provider = src.provider;
12019                         dst.proc = r;
12020                         dst.notifyAll();
12021                     }
12022                     updateOomAdjLocked(r, true);
12023                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12024                             src.info.authority);
12025                 }
12026             }
12027
12028             Binder.restoreCallingIdentity(origId);
12029         }
12030     }
12031
12032     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12033         ContentProviderConnection conn;
12034         try {
12035             conn = (ContentProviderConnection)connection;
12036         } catch (ClassCastException e) {
12037             String msg ="refContentProvider: " + connection
12038                     + " not a ContentProviderConnection";
12039             Slog.w(TAG, msg);
12040             throw new IllegalArgumentException(msg);
12041         }
12042         if (conn == null) {
12043             throw new NullPointerException("connection is null");
12044         }
12045
12046         synchronized (this) {
12047             if (stable > 0) {
12048                 conn.numStableIncs += stable;
12049             }
12050             stable = conn.stableCount + stable;
12051             if (stable < 0) {
12052                 throw new IllegalStateException("stableCount < 0: " + stable);
12053             }
12054
12055             if (unstable > 0) {
12056                 conn.numUnstableIncs += unstable;
12057             }
12058             unstable = conn.unstableCount + unstable;
12059             if (unstable < 0) {
12060                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12061             }
12062
12063             if ((stable+unstable) <= 0) {
12064                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12065                         + stable + " unstable=" + unstable);
12066             }
12067             conn.stableCount = stable;
12068             conn.unstableCount = unstable;
12069             return !conn.dead;
12070         }
12071     }
12072
12073     public void unstableProviderDied(IBinder connection) {
12074         ContentProviderConnection conn;
12075         try {
12076             conn = (ContentProviderConnection)connection;
12077         } catch (ClassCastException e) {
12078             String msg ="refContentProvider: " + connection
12079                     + " not a ContentProviderConnection";
12080             Slog.w(TAG, msg);
12081             throw new IllegalArgumentException(msg);
12082         }
12083         if (conn == null) {
12084             throw new NullPointerException("connection is null");
12085         }
12086
12087         // Safely retrieve the content provider associated with the connection.
12088         IContentProvider provider;
12089         synchronized (this) {
12090             provider = conn.provider.provider;
12091         }
12092
12093         if (provider == null) {
12094             // Um, yeah, we're way ahead of you.
12095             return;
12096         }
12097
12098         // Make sure the caller is being honest with us.
12099         if (provider.asBinder().pingBinder()) {
12100             // Er, no, still looks good to us.
12101             synchronized (this) {
12102                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12103                         + " says " + conn + " died, but we don't agree");
12104                 return;
12105             }
12106         }
12107
12108         // Well look at that!  It's dead!
12109         synchronized (this) {
12110             if (conn.provider.provider != provider) {
12111                 // But something changed...  good enough.
12112                 return;
12113             }
12114
12115             ProcessRecord proc = conn.provider.proc;
12116             if (proc == null || proc.thread == null) {
12117                 // Seems like the process is already cleaned up.
12118                 return;
12119             }
12120
12121             // As far as we're concerned, this is just like receiving a
12122             // death notification...  just a bit prematurely.
12123             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12124                     + ") early provider death");
12125             final long ident = Binder.clearCallingIdentity();
12126             try {
12127                 appDiedLocked(proc);
12128             } finally {
12129                 Binder.restoreCallingIdentity(ident);
12130             }
12131         }
12132     }
12133
12134     @Override
12135     public void appNotRespondingViaProvider(IBinder connection) {
12136         enforceCallingPermission(
12137                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12138
12139         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12140         if (conn == null) {
12141             Slog.w(TAG, "ContentProviderConnection is null");
12142             return;
12143         }
12144
12145         final ProcessRecord host = conn.provider.proc;
12146         if (host == null) {
12147             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12148             return;
12149         }
12150
12151         mHandler.post(new Runnable() {
12152             @Override
12153             public void run() {
12154                 mAppErrors.appNotResponding(host, null, null, false,
12155                         "ContentProvider not responding");
12156             }
12157         });
12158     }
12159
12160     public final void installSystemProviders() {
12161         List<ProviderInfo> providers;
12162         synchronized (this) {
12163             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12164             providers = generateApplicationProvidersLocked(app);
12165             if (providers != null) {
12166                 for (int i=providers.size()-1; i>=0; i--) {
12167                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12168                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12169                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12170                                 + ": not system .apk");
12171                         providers.remove(i);
12172                     }
12173                 }
12174             }
12175         }
12176         if (providers != null) {
12177             mSystemThread.installSystemProviders(providers);
12178         }
12179
12180         mConstants.start(mContext.getContentResolver());
12181         mCoreSettingsObserver = new CoreSettingsObserver(this);
12182         mFontScaleSettingObserver = new FontScaleSettingObserver();
12183
12184         // Now that the settings provider is published we can consider sending
12185         // in a rescue party.
12186         RescueParty.onSettingsProviderPublished(mContext);
12187
12188         //mUsageStatsService.monitorPackages();
12189     }
12190
12191     private void startPersistentApps(int matchFlags) {
12192         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12193
12194         synchronized (this) {
12195             try {
12196                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12197                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12198                 for (ApplicationInfo app : apps) {
12199                     if (!"android".equals(app.packageName)) {
12200                         addAppLocked(app, null, false, null /* ABI override */);
12201                     }
12202                 }
12203             } catch (RemoteException ex) {
12204             }
12205         }
12206     }
12207
12208     /**
12209      * When a user is unlocked, we need to install encryption-unaware providers
12210      * belonging to any running apps.
12211      */
12212     private void installEncryptionUnawareProviders(int userId) {
12213         // We're only interested in providers that are encryption unaware, and
12214         // we don't care about uninstalled apps, since there's no way they're
12215         // running at this point.
12216         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12217
12218         synchronized (this) {
12219             final int NP = mProcessNames.getMap().size();
12220             for (int ip = 0; ip < NP; ip++) {
12221                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12222                 final int NA = apps.size();
12223                 for (int ia = 0; ia < NA; ia++) {
12224                     final ProcessRecord app = apps.valueAt(ia);
12225                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12226
12227                     final int NG = app.pkgList.size();
12228                     for (int ig = 0; ig < NG; ig++) {
12229                         try {
12230                             final String pkgName = app.pkgList.keyAt(ig);
12231                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12232                                     .getPackageInfo(pkgName, matchFlags, userId);
12233                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12234                                 for (ProviderInfo pi : pkgInfo.providers) {
12235                                     // TODO: keep in sync with generateApplicationProvidersLocked
12236                                     final boolean processMatch = Objects.equals(pi.processName,
12237                                             app.processName) || pi.multiprocess;
12238                                     final boolean userMatch = isSingleton(pi.processName,
12239                                             pi.applicationInfo, pi.name, pi.flags)
12240                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12241                                     if (processMatch && userMatch) {
12242                                         Log.v(TAG, "Installing " + pi);
12243                                         app.thread.scheduleInstallProvider(pi);
12244                                     } else {
12245                                         Log.v(TAG, "Skipping " + pi);
12246                                     }
12247                                 }
12248                             }
12249                         } catch (RemoteException ignored) {
12250                         }
12251                     }
12252                 }
12253             }
12254         }
12255     }
12256
12257     /**
12258      * Allows apps to retrieve the MIME type of a URI.
12259      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12260      * users, then it does not need permission to access the ContentProvider.
12261      * Either, it needs cross-user uri grants.
12262      *
12263      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12264      *
12265      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12266      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12267      */
12268     public String getProviderMimeType(Uri uri, int userId) {
12269         enforceNotIsolatedCaller("getProviderMimeType");
12270         final String name = uri.getAuthority();
12271         int callingUid = Binder.getCallingUid();
12272         int callingPid = Binder.getCallingPid();
12273         long ident = 0;
12274         boolean clearedIdentity = false;
12275         synchronized (this) {
12276             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12277         }
12278         if (canClearIdentity(callingPid, callingUid, userId)) {
12279             clearedIdentity = true;
12280             ident = Binder.clearCallingIdentity();
12281         }
12282         ContentProviderHolder holder = null;
12283         try {
12284             holder = getContentProviderExternalUnchecked(name, null, userId);
12285             if (holder != null) {
12286                 return holder.provider.getType(uri);
12287             }
12288         } catch (RemoteException e) {
12289             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12290             return null;
12291         } catch (Exception e) {
12292             Log.w(TAG, "Exception while determining type of " + uri, e);
12293             return null;
12294         } finally {
12295             // We need to clear the identity to call removeContentProviderExternalUnchecked
12296             if (!clearedIdentity) {
12297                 ident = Binder.clearCallingIdentity();
12298             }
12299             try {
12300                 if (holder != null) {
12301                     removeContentProviderExternalUnchecked(name, null, userId);
12302                 }
12303             } finally {
12304                 Binder.restoreCallingIdentity(ident);
12305             }
12306         }
12307
12308         return null;
12309     }
12310
12311     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12312         if (UserHandle.getUserId(callingUid) == userId) {
12313             return true;
12314         }
12315         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12316                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12317                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12318                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12319                 return true;
12320         }
12321         return false;
12322     }
12323
12324     // =========================================================
12325     // GLOBAL MANAGEMENT
12326     // =========================================================
12327
12328     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12329             boolean isolated, int isolatedUid) {
12330         String proc = customProcess != null ? customProcess : info.processName;
12331         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12332         final int userId = UserHandle.getUserId(info.uid);
12333         int uid = info.uid;
12334         if (isolated) {
12335             if (isolatedUid == 0) {
12336                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12337                 while (true) {
12338                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12339                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12340                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12341                     }
12342                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12343                     mNextIsolatedProcessUid++;
12344                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12345                         // No process for this uid, use it.
12346                         break;
12347                     }
12348                     stepsLeft--;
12349                     if (stepsLeft <= 0) {
12350                         return null;
12351                     }
12352                 }
12353             } else {
12354                 // Special case for startIsolatedProcess (internal only), where
12355                 // the uid of the isolated process is specified by the caller.
12356                 uid = isolatedUid;
12357             }
12358             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12359
12360             // Register the isolated UID with this application so BatteryStats knows to
12361             // attribute resource usage to the application.
12362             //
12363             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12364             // about the process state of the isolated UID *before* it is registered with the
12365             // owning application.
12366             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12367         }
12368         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12369         if (!mBooted && !mBooting
12370                 && userId == UserHandle.USER_SYSTEM
12371                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12372             r.persistent = true;
12373             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12374         }
12375         addProcessNameLocked(r);
12376         return r;
12377     }
12378
12379     private boolean uidOnBackgroundWhitelist(final int uid) {
12380         final int appId = UserHandle.getAppId(uid);
12381         final int[] whitelist = mBackgroundAppIdWhitelist;
12382         final int N = whitelist.length;
12383         for (int i = 0; i < N; i++) {
12384             if (appId == whitelist[i]) {
12385                 return true;
12386             }
12387         }
12388         return false;
12389     }
12390
12391     @Override
12392     public void backgroundWhitelistUid(final int uid) {
12393         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12394             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12395         }
12396
12397         if (DEBUG_BACKGROUND_CHECK) {
12398             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12399         }
12400         synchronized (this) {
12401             final int N = mBackgroundAppIdWhitelist.length;
12402             int[] newList = new int[N+1];
12403             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12404             newList[N] = UserHandle.getAppId(uid);
12405             mBackgroundAppIdWhitelist = newList;
12406         }
12407     }
12408
12409     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12410             String abiOverride) {
12411         ProcessRecord app;
12412         if (!isolated) {
12413             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12414                     info.uid, true);
12415         } else {
12416             app = null;
12417         }
12418
12419         if (app == null) {
12420             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12421             updateLruProcessLocked(app, false, null);
12422             updateOomAdjLocked();
12423         }
12424
12425         // This package really, really can not be stopped.
12426         try {
12427             AppGlobals.getPackageManager().setPackageStoppedState(
12428                     info.packageName, false, UserHandle.getUserId(app.uid));
12429         } catch (RemoteException e) {
12430         } catch (IllegalArgumentException e) {
12431             Slog.w(TAG, "Failed trying to unstop package "
12432                     + info.packageName + ": " + e);
12433         }
12434
12435         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12436             app.persistent = true;
12437             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12438         }
12439         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12440             mPersistentStartingProcesses.add(app);
12441             startProcessLocked(app, "added application",
12442                     customProcess != null ? customProcess : app.processName, abiOverride,
12443                     null /* entryPoint */, null /* entryPointArgs */);
12444         }
12445
12446         return app;
12447     }
12448
12449     public void unhandledBack() {
12450         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12451                 "unhandledBack()");
12452
12453         synchronized(this) {
12454             final long origId = Binder.clearCallingIdentity();
12455             try {
12456                 getFocusedStack().unhandledBackLocked();
12457             } finally {
12458                 Binder.restoreCallingIdentity(origId);
12459             }
12460         }
12461     }
12462
12463     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12464         enforceNotIsolatedCaller("openContentUri");
12465         final int userId = UserHandle.getCallingUserId();
12466         final Uri uri = Uri.parse(uriString);
12467         String name = uri.getAuthority();
12468         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12469         ParcelFileDescriptor pfd = null;
12470         if (cph != null) {
12471             // We record the binder invoker's uid in thread-local storage before
12472             // going to the content provider to open the file.  Later, in the code
12473             // that handles all permissions checks, we look for this uid and use
12474             // that rather than the Activity Manager's own uid.  The effect is that
12475             // we do the check against the caller's permissions even though it looks
12476             // to the content provider like the Activity Manager itself is making
12477             // the request.
12478             Binder token = new Binder();
12479             sCallerIdentity.set(new Identity(
12480                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12481             try {
12482                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12483             } catch (FileNotFoundException e) {
12484                 // do nothing; pfd will be returned null
12485             } finally {
12486                 // Ensure that whatever happens, we clean up the identity state
12487                 sCallerIdentity.remove();
12488                 // Ensure we're done with the provider.
12489                 removeContentProviderExternalUnchecked(name, null, userId);
12490             }
12491         } else {
12492             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12493         }
12494         return pfd;
12495     }
12496
12497     // Actually is sleeping or shutting down or whatever else in the future
12498     // is an inactive state.
12499     boolean isSleepingOrShuttingDownLocked() {
12500         return isSleepingLocked() || mShuttingDown;
12501     }
12502
12503     boolean isShuttingDownLocked() {
12504         return mShuttingDown;
12505     }
12506
12507     boolean isSleepingLocked() {
12508         return mSleeping;
12509     }
12510
12511     void onWakefulnessChanged(int wakefulness) {
12512         synchronized(this) {
12513             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12514             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12515             mWakefulness = wakefulness;
12516
12517             if (wasAwake != isAwake) {
12518                 // Also update state in a special way for running foreground services UI.
12519                 mServices.updateScreenStateLocked(isAwake);
12520                 mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
12521                         .sendToTarget();
12522             }
12523         }
12524     }
12525
12526     void finishRunningVoiceLocked() {
12527         if (mRunningVoice != null) {
12528             mRunningVoice = null;
12529             mVoiceWakeLock.release();
12530             updateSleepIfNeededLocked();
12531         }
12532     }
12533
12534     void startTimeTrackingFocusedActivityLocked() {
12535         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12536         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12537             mCurAppTimeTracker.start(resumedActivity.packageName);
12538         }
12539     }
12540
12541     void updateSleepIfNeededLocked() {
12542         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12543         final boolean wasSleeping = mSleeping;
12544
12545         if (!shouldSleep) {
12546             // If wasSleeping is true, we need to wake up activity manager state from when
12547             // we started sleeping. In either case, we need to apply the sleep tokens, which
12548             // will wake up stacks or put them to sleep as appropriate.
12549             if (wasSleeping) {
12550                 mSleeping = false;
12551                 startTimeTrackingFocusedActivityLocked();
12552                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12553                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12554             }
12555             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12556             if (wasSleeping) {
12557                 updateOomAdjLocked();
12558             }
12559         } else if (!mSleeping && shouldSleep) {
12560             mSleeping = true;
12561             if (mCurAppTimeTracker != null) {
12562                 mCurAppTimeTracker.stop();
12563             }
12564             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12565             mStackSupervisor.goingToSleepLocked();
12566             updateOomAdjLocked();
12567         }
12568     }
12569
12570     /** Pokes the task persister. */
12571     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12572         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12573     }
12574
12575     /**
12576      * Notifies all listeners when the pinned stack animation starts.
12577      */
12578     @Override
12579     public void notifyPinnedStackAnimationStarted() {
12580         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12581     }
12582
12583     /**
12584      * Notifies all listeners when the pinned stack animation ends.
12585      */
12586     @Override
12587     public void notifyPinnedStackAnimationEnded() {
12588         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12589     }
12590
12591     @Override
12592     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12593         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12594     }
12595
12596     @Override
12597     public boolean shutdown(int timeout) {
12598         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12599                 != PackageManager.PERMISSION_GRANTED) {
12600             throw new SecurityException("Requires permission "
12601                     + android.Manifest.permission.SHUTDOWN);
12602         }
12603
12604         boolean timedout = false;
12605
12606         synchronized(this) {
12607             mShuttingDown = true;
12608             mStackSupervisor.prepareForShutdownLocked();
12609             updateEventDispatchingLocked();
12610             timedout = mStackSupervisor.shutdownLocked(timeout);
12611         }
12612
12613         mAppOpsService.shutdown();
12614         if (mUsageStatsService != null) {
12615             mUsageStatsService.prepareShutdown();
12616         }
12617         mBatteryStatsService.shutdown();
12618         synchronized (this) {
12619             mProcessStats.shutdownLocked();
12620             notifyTaskPersisterLocked(null, true);
12621         }
12622
12623         return timedout;
12624     }
12625
12626     public final void activitySlept(IBinder token) {
12627         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12628
12629         final long origId = Binder.clearCallingIdentity();
12630
12631         synchronized (this) {
12632             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12633             if (r != null) {
12634                 mStackSupervisor.activitySleptLocked(r);
12635             }
12636         }
12637
12638         Binder.restoreCallingIdentity(origId);
12639     }
12640
12641     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12642         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12643         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12644         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12645             boolean wasRunningVoice = mRunningVoice != null;
12646             mRunningVoice = session;
12647             if (!wasRunningVoice) {
12648                 mVoiceWakeLock.acquire();
12649                 updateSleepIfNeededLocked();
12650             }
12651         }
12652     }
12653
12654     private void updateEventDispatchingLocked() {
12655         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12656     }
12657
12658     @Override
12659     public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12660         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12661                 != PackageManager.PERMISSION_GRANTED) {
12662             throw new SecurityException("Requires permission "
12663                     + android.Manifest.permission.DEVICE_POWER);
12664         }
12665
12666         synchronized(this) {
12667             long ident = Binder.clearCallingIdentity();
12668             try {
12669                 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12670             } finally {
12671                 Binder.restoreCallingIdentity(ident);
12672             }
12673         }
12674
12675         mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
12676                 .sendToTarget();
12677     }
12678
12679     @Override
12680     public void notifyLockedProfile(@UserIdInt int userId) {
12681         try {
12682             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12683                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12684             }
12685         } catch (RemoteException ex) {
12686             throw new SecurityException("Fail to check is caller a privileged app", ex);
12687         }
12688
12689         synchronized (this) {
12690             final long ident = Binder.clearCallingIdentity();
12691             try {
12692                 if (mUserController.shouldConfirmCredentials(userId)) {
12693                     if (mKeyguardController.isKeyguardLocked()) {
12694                         // Showing launcher to avoid user entering credential twice.
12695                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12696                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12697                     }
12698                     mStackSupervisor.lockAllProfileTasks(userId);
12699                 }
12700             } finally {
12701                 Binder.restoreCallingIdentity(ident);
12702             }
12703         }
12704     }
12705
12706     @Override
12707     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12708         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12709         synchronized (this) {
12710             final long ident = Binder.clearCallingIdentity();
12711             try {
12712                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12713             } finally {
12714                 Binder.restoreCallingIdentity(ident);
12715             }
12716         }
12717     }
12718
12719     @Override
12720     public void stopAppSwitches() {
12721         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12722                 != PackageManager.PERMISSION_GRANTED) {
12723             throw new SecurityException("viewquires permission "
12724                     + android.Manifest.permission.STOP_APP_SWITCHES);
12725         }
12726
12727         synchronized(this) {
12728             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12729                     + APP_SWITCH_DELAY_TIME;
12730             mDidAppSwitch = false;
12731             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12732             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12733             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12734         }
12735     }
12736
12737     public void resumeAppSwitches() {
12738         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12739                 != PackageManager.PERMISSION_GRANTED) {
12740             throw new SecurityException("Requires permission "
12741                     + android.Manifest.permission.STOP_APP_SWITCHES);
12742         }
12743
12744         synchronized(this) {
12745             // Note that we don't execute any pending app switches... we will
12746             // let those wait until either the timeout, or the next start
12747             // activity request.
12748             mAppSwitchesAllowedTime = 0;
12749         }
12750     }
12751
12752     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12753             int callingPid, int callingUid, String name) {
12754         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12755             return true;
12756         }
12757
12758         int perm = checkComponentPermission(
12759                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12760                 sourceUid, -1, true);
12761         if (perm == PackageManager.PERMISSION_GRANTED) {
12762             return true;
12763         }
12764
12765         // If the actual IPC caller is different from the logical source, then
12766         // also see if they are allowed to control app switches.
12767         if (callingUid != -1 && callingUid != sourceUid) {
12768             perm = checkComponentPermission(
12769                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12770                     callingUid, -1, true);
12771             if (perm == PackageManager.PERMISSION_GRANTED) {
12772                 return true;
12773             }
12774         }
12775
12776         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12777         return false;
12778     }
12779
12780     public void setDebugApp(String packageName, boolean waitForDebugger,
12781             boolean persistent) {
12782         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12783                 "setDebugApp()");
12784
12785         long ident = Binder.clearCallingIdentity();
12786         try {
12787             // Note that this is not really thread safe if there are multiple
12788             // callers into it at the same time, but that's not a situation we
12789             // care about.
12790             if (persistent) {
12791                 final ContentResolver resolver = mContext.getContentResolver();
12792                 Settings.Global.putString(
12793                     resolver, Settings.Global.DEBUG_APP,
12794                     packageName);
12795                 Settings.Global.putInt(
12796                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12797                     waitForDebugger ? 1 : 0);
12798             }
12799
12800             synchronized (this) {
12801                 if (!persistent) {
12802                     mOrigDebugApp = mDebugApp;
12803                     mOrigWaitForDebugger = mWaitForDebugger;
12804                 }
12805                 mDebugApp = packageName;
12806                 mWaitForDebugger = waitForDebugger;
12807                 mDebugTransient = !persistent;
12808                 if (packageName != null) {
12809                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12810                             false, UserHandle.USER_ALL, "set debug app");
12811                 }
12812             }
12813         } finally {
12814             Binder.restoreCallingIdentity(ident);
12815         }
12816     }
12817
12818     /**
12819      * Set or remove an agent to be run whenever an app with the given process name starts.
12820      *
12821      * This method will not check whether the given process name matches a debuggable app. That
12822      * would require scanning all current packages, and a rescan when new packages are installed
12823      * or updated.
12824      *
12825      * Instead, do the check when an application is started and matched to a stored agent.
12826      *
12827      * @param packageName the process name of the app.
12828      * @param agent the agent string to be used, or null to remove any previously set agent.
12829      */
12830     @Override
12831     public void setAgentApp(@NonNull String packageName, @Nullable String agent) {
12832         synchronized (this) {
12833             // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
12834             // its own permission.
12835             if (checkCallingPermission(
12836                     android.Manifest.permission.SET_ACTIVITY_WATCHER) !=
12837                         PackageManager.PERMISSION_GRANTED) {
12838                 throw new SecurityException(
12839                         "Requires permission " + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12840             }
12841
12842             if (agent == null) {
12843                 if (mAppAgentMap != null) {
12844                     mAppAgentMap.remove(packageName);
12845                     if (mAppAgentMap.isEmpty()) {
12846                         mAppAgentMap = null;
12847                     }
12848                 }
12849             } else {
12850                 if (mAppAgentMap == null) {
12851                     mAppAgentMap = new HashMap<>();
12852                 }
12853                 if (mAppAgentMap.size() >= 100) {
12854                     // Limit the size of the map, to avoid OOMEs.
12855                     Slog.e(TAG, "App agent map has too many entries, cannot add " + packageName
12856                             + "/" + agent);
12857                     return;
12858                 }
12859                 mAppAgentMap.put(packageName, agent);
12860             }
12861         }
12862     }
12863
12864     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12865         synchronized (this) {
12866             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12867             if (!isDebuggable) {
12868                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12869                     throw new SecurityException("Process not debuggable: " + app.packageName);
12870                 }
12871             }
12872
12873             mTrackAllocationApp = processName;
12874         }
12875     }
12876
12877     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12878         synchronized (this) {
12879             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12880             if (!isDebuggable) {
12881                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12882                     throw new SecurityException("Process not debuggable: " + app.packageName);
12883                 }
12884             }
12885             mProfileApp = processName;
12886
12887             if (mProfilerInfo != null) {
12888                 if (mProfilerInfo.profileFd != null) {
12889                     try {
12890                         mProfilerInfo.profileFd.close();
12891                     } catch (IOException e) {
12892                     }
12893                 }
12894             }
12895             mProfilerInfo = new ProfilerInfo(profilerInfo);
12896             mProfileType = 0;
12897         }
12898     }
12899
12900     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12901         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12902         if (!isDebuggable) {
12903             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12904                 throw new SecurityException("Process not debuggable: " + app.packageName);
12905             }
12906         }
12907         mNativeDebuggingApp = processName;
12908     }
12909
12910     @Override
12911     public void setAlwaysFinish(boolean enabled) {
12912         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12913                 "setAlwaysFinish()");
12914
12915         long ident = Binder.clearCallingIdentity();
12916         try {
12917             Settings.Global.putInt(
12918                     mContext.getContentResolver(),
12919                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12920
12921             synchronized (this) {
12922                 mAlwaysFinishActivities = enabled;
12923             }
12924         } finally {
12925             Binder.restoreCallingIdentity(ident);
12926         }
12927     }
12928
12929     @Override
12930     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12931         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12932                 "setActivityController()");
12933         synchronized (this) {
12934             mController = controller;
12935             mControllerIsAMonkey = imAMonkey;
12936             Watchdog.getInstance().setActivityController(controller);
12937         }
12938     }
12939
12940     @Override
12941     public void setUserIsMonkey(boolean userIsMonkey) {
12942         synchronized (this) {
12943             synchronized (mPidsSelfLocked) {
12944                 final int callingPid = Binder.getCallingPid();
12945                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12946                 if (proc == null) {
12947                     throw new SecurityException("Unknown process: " + callingPid);
12948                 }
12949                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12950                     throw new SecurityException("Only an instrumentation process "
12951                             + "with a UiAutomation can call setUserIsMonkey");
12952                 }
12953             }
12954             mUserIsMonkey = userIsMonkey;
12955         }
12956     }
12957
12958     @Override
12959     public boolean isUserAMonkey() {
12960         synchronized (this) {
12961             // If there is a controller also implies the user is a monkey.
12962             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12963         }
12964     }
12965
12966     /**
12967      * @deprecated This method is only used by a few internal components and it will soon be
12968      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12969      * No new code should be calling it.
12970      */
12971     @Deprecated
12972     @Override
12973     public void requestBugReport(int bugreportType) {
12974         String extraOptions = null;
12975         switch (bugreportType) {
12976             case ActivityManager.BUGREPORT_OPTION_FULL:
12977                 // Default options.
12978                 break;
12979             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12980                 extraOptions = "bugreportplus";
12981                 break;
12982             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12983                 extraOptions = "bugreportremote";
12984                 break;
12985             case ActivityManager.BUGREPORT_OPTION_WEAR:
12986                 extraOptions = "bugreportwear";
12987                 break;
12988             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12989                 extraOptions = "bugreporttelephony";
12990                 break;
12991             default:
12992                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12993                         + bugreportType);
12994         }
12995         // Always log caller, even if it does not have permission to dump.
12996         String type = extraOptions == null ? "bugreport" : extraOptions;
12997         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12998
12999         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
13000         if (extraOptions != null) {
13001             SystemProperties.set("dumpstate.options", extraOptions);
13002         }
13003         SystemProperties.set("ctl.start", "bugreport");
13004     }
13005
13006     /**
13007      * @deprecated This method is only used by a few internal components and it will soon be
13008      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
13009      * No new code should be calling it.
13010      */
13011     @Deprecated
13012     @Override
13013     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
13014
13015         if (!TextUtils.isEmpty(shareTitle)) {
13016             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
13017                 String errorStr = "shareTitle should be less than " +
13018                         MAX_BUGREPORT_TITLE_SIZE + " characters";
13019                 throw new IllegalArgumentException(errorStr);
13020             } else {
13021                 if (!TextUtils.isEmpty(shareDescription)) {
13022                     int length;
13023                     try {
13024                         length = shareDescription.getBytes("UTF-8").length;
13025                     } catch (UnsupportedEncodingException e) {
13026                         String errorStr = "shareDescription: UnsupportedEncodingException";
13027                         throw new IllegalArgumentException(errorStr);
13028                     }
13029                     if (length > SystemProperties.PROP_VALUE_MAX) {
13030                         String errorStr = "shareTitle should be less than " +
13031                                 SystemProperties.PROP_VALUE_MAX + " bytes";
13032                         throw new IllegalArgumentException(errorStr);
13033                     } else {
13034                         SystemProperties.set("dumpstate.options.description", shareDescription);
13035                     }
13036                 }
13037                 SystemProperties.set("dumpstate.options.title", shareTitle);
13038             }
13039         }
13040
13041         Slog.d(TAG, "Bugreport notification title " + shareTitle
13042                 + " description " + shareDescription);
13043         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
13044     }
13045
13046     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
13047         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
13048     }
13049
13050     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
13051         if (r != null && (r.instr != null || r.usingWrapper)) {
13052             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
13053         }
13054         return KEY_DISPATCHING_TIMEOUT;
13055     }
13056
13057     @Override
13058     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
13059         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13060                 != PackageManager.PERMISSION_GRANTED) {
13061             throw new SecurityException("Requires permission "
13062                     + android.Manifest.permission.FILTER_EVENTS);
13063         }
13064         ProcessRecord proc;
13065         long timeout;
13066         synchronized (this) {
13067             synchronized (mPidsSelfLocked) {
13068                 proc = mPidsSelfLocked.get(pid);
13069             }
13070             timeout = getInputDispatchingTimeoutLocked(proc);
13071         }
13072
13073         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13074             return -1;
13075         }
13076
13077         return timeout;
13078     }
13079
13080     /**
13081      * Handle input dispatching timeouts.
13082      * Returns whether input dispatching should be aborted or not.
13083      */
13084     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13085             final ActivityRecord activity, final ActivityRecord parent,
13086             final boolean aboveSystem, String reason) {
13087         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13088                 != PackageManager.PERMISSION_GRANTED) {
13089             throw new SecurityException("Requires permission "
13090                     + android.Manifest.permission.FILTER_EVENTS);
13091         }
13092
13093         final String annotation;
13094         if (reason == null) {
13095             annotation = "Input dispatching timed out";
13096         } else {
13097             annotation = "Input dispatching timed out (" + reason + ")";
13098         }
13099
13100         if (proc != null) {
13101             synchronized (this) {
13102                 if (proc.debugging) {
13103                     return false;
13104                 }
13105
13106                 if (proc.instr != null) {
13107                     Bundle info = new Bundle();
13108                     info.putString("shortMsg", "keyDispatchingTimedOut");
13109                     info.putString("longMsg", annotation);
13110                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13111                     return true;
13112                 }
13113             }
13114             mHandler.post(new Runnable() {
13115                 @Override
13116                 public void run() {
13117                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13118                 }
13119             });
13120         }
13121
13122         return true;
13123     }
13124
13125     @Override
13126     public Bundle getAssistContextExtras(int requestType) {
13127         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13128                 null, null, true /* focused */, true /* newSessionId */,
13129                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13130         if (pae == null) {
13131             return null;
13132         }
13133         synchronized (pae) {
13134             while (!pae.haveResult) {
13135                 try {
13136                     pae.wait();
13137                 } catch (InterruptedException e) {
13138                 }
13139             }
13140         }
13141         synchronized (this) {
13142             buildAssistBundleLocked(pae, pae.result);
13143             mPendingAssistExtras.remove(pae);
13144             mUiHandler.removeCallbacks(pae);
13145         }
13146         return pae.extras;
13147     }
13148
13149     @Override
13150     public boolean isAssistDataAllowedOnCurrentActivity() {
13151         int userId;
13152         synchronized (this) {
13153             final ActivityStack focusedStack = getFocusedStack();
13154             if (focusedStack == null || focusedStack.isAssistantStack()) {
13155                 return false;
13156             }
13157
13158             final ActivityRecord activity = focusedStack.topActivity();
13159             if (activity == null) {
13160                 return false;
13161             }
13162             userId = activity.userId;
13163         }
13164         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13165                 Context.DEVICE_POLICY_SERVICE);
13166         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13167     }
13168
13169     @Override
13170     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13171         long ident = Binder.clearCallingIdentity();
13172         try {
13173             synchronized (this) {
13174                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13175                 ActivityRecord top = getFocusedStack().topActivity();
13176                 if (top != caller) {
13177                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13178                             + " is not current top " + top);
13179                     return false;
13180                 }
13181                 if (!top.nowVisible) {
13182                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13183                             + " is not visible");
13184                     return false;
13185                 }
13186             }
13187             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13188                     token);
13189         } finally {
13190             Binder.restoreCallingIdentity(ident);
13191         }
13192     }
13193
13194     @Override
13195     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13196             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13197         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13198                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13199                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13200     }
13201
13202     @Override
13203     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13204             IBinder activityToken, int flags) {
13205         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13206                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13207                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13208     }
13209
13210     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13211             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13212             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13213             int flags) {
13214         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13215                 "enqueueAssistContext()");
13216
13217         synchronized (this) {
13218             ActivityRecord activity = getFocusedStack().topActivity();
13219             if (activity == null) {
13220                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13221                 return null;
13222             }
13223             if (activity.app == null || activity.app.thread == null) {
13224                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13225                 return null;
13226             }
13227             if (focused) {
13228                 if (activityToken != null) {
13229                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13230                     if (activity != caller) {
13231                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13232                                 + " is not current top " + activity);
13233                         return null;
13234                     }
13235                 }
13236             } else {
13237                 activity = ActivityRecord.forTokenLocked(activityToken);
13238                 if (activity == null) {
13239                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13240                             + " couldn't be found");
13241                     return null;
13242                 }
13243                 if (activity.app == null || activity.app.thread == null) {
13244                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13245                     return null;
13246                 }
13247             }
13248
13249             PendingAssistExtras pae;
13250             Bundle extras = new Bundle();
13251             if (args != null) {
13252                 extras.putAll(args);
13253             }
13254             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13255             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13256
13257             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13258                     userHandle);
13259             pae.isHome = activity.isHomeActivity();
13260
13261             // Increment the sessionId if necessary
13262             if (newSessionId) {
13263                 mViSessionId++;
13264             }
13265             try {
13266                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13267                         mViSessionId, flags);
13268                 mPendingAssistExtras.add(pae);
13269                 mUiHandler.postDelayed(pae, timeout);
13270             } catch (RemoteException e) {
13271                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13272                 return null;
13273             }
13274             return pae;
13275         }
13276     }
13277
13278     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13279         IResultReceiver receiver;
13280         synchronized (this) {
13281             mPendingAssistExtras.remove(pae);
13282             receiver = pae.receiver;
13283         }
13284         if (receiver != null) {
13285             // Caller wants result sent back to them.
13286             Bundle sendBundle = new Bundle();
13287             // At least return the receiver extras
13288             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13289                     pae.receiverExtras);
13290             try {
13291                 pae.receiver.send(0, sendBundle);
13292             } catch (RemoteException e) {
13293             }
13294         }
13295     }
13296
13297     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13298         if (result != null) {
13299             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13300         }
13301         if (pae.hint != null) {
13302             pae.extras.putBoolean(pae.hint, true);
13303         }
13304     }
13305
13306     /** Called from an app when assist data is ready. */
13307     @Override
13308     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13309             AssistContent content, Uri referrer) {
13310         PendingAssistExtras pae = (PendingAssistExtras)token;
13311         synchronized (pae) {
13312             pae.result = extras;
13313             pae.structure = structure;
13314             pae.content = content;
13315             if (referrer != null) {
13316                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13317             }
13318             if (structure != null) {
13319                 structure.setHomeActivity(pae.isHome);
13320             }
13321             pae.haveResult = true;
13322             pae.notifyAll();
13323             if (pae.intent == null && pae.receiver == null) {
13324                 // Caller is just waiting for the result.
13325                 return;
13326             }
13327         }
13328         // We are now ready to launch the assist activity.
13329         IResultReceiver sendReceiver = null;
13330         Bundle sendBundle = null;
13331         synchronized (this) {
13332             buildAssistBundleLocked(pae, extras);
13333             boolean exists = mPendingAssistExtras.remove(pae);
13334             mUiHandler.removeCallbacks(pae);
13335             if (!exists) {
13336                 // Timed out.
13337                 return;
13338             }
13339             if ((sendReceiver=pae.receiver) != null) {
13340                 // Caller wants result sent back to them.
13341                 sendBundle = new Bundle();
13342                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13343                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13344                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13345                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13346                         pae.receiverExtras);
13347             }
13348         }
13349         if (sendReceiver != null) {
13350             try {
13351                 sendReceiver.send(0, sendBundle);
13352             } catch (RemoteException e) {
13353             }
13354             return;
13355         }
13356
13357         final long ident = Binder.clearCallingIdentity();
13358         try {
13359             if (TextUtils.equals(pae.intent.getAction(),
13360                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13361                 pae.intent.putExtras(pae.extras);
13362                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13363             } else {
13364                 pae.intent.replaceExtras(pae.extras);
13365                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13366                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13367                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13368                 closeSystemDialogs("assist");
13369
13370                 try {
13371                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13372                 } catch (ActivityNotFoundException e) {
13373                     Slog.w(TAG, "No activity to handle assist action.", e);
13374                 }
13375             }
13376         } finally {
13377             Binder.restoreCallingIdentity(ident);
13378         }
13379     }
13380
13381     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13382             Bundle args) {
13383         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13384                 true /* focused */, true /* newSessionId */, userHandle, args,
13385                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13386     }
13387
13388     public void registerProcessObserver(IProcessObserver observer) {
13389         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13390                 "registerProcessObserver()");
13391         synchronized (this) {
13392             mProcessObservers.register(observer);
13393         }
13394     }
13395
13396     @Override
13397     public void unregisterProcessObserver(IProcessObserver observer) {
13398         synchronized (this) {
13399             mProcessObservers.unregister(observer);
13400         }
13401     }
13402
13403     @Override
13404     public int getUidProcessState(int uid, String callingPackage) {
13405         if (!hasUsageStatsPermission(callingPackage)) {
13406             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13407                     "getUidProcessState");
13408         }
13409
13410         synchronized (this) {
13411             UidRecord uidRec = mActiveUids.get(uid);
13412             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13413         }
13414     }
13415
13416     @Override
13417     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13418             String callingPackage) {
13419         if (!hasUsageStatsPermission(callingPackage)) {
13420             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13421                     "registerUidObserver");
13422         }
13423         synchronized (this) {
13424             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13425                     callingPackage, which, cutpoint));
13426         }
13427     }
13428
13429     @Override
13430     public void unregisterUidObserver(IUidObserver observer) {
13431         synchronized (this) {
13432             mUidObservers.unregister(observer);
13433         }
13434     }
13435
13436     @Override
13437     public boolean convertFromTranslucent(IBinder token) {
13438         final long origId = Binder.clearCallingIdentity();
13439         try {
13440             synchronized (this) {
13441                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13442                 if (r == null) {
13443                     return false;
13444                 }
13445                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13446                 if (translucentChanged) {
13447                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13448                 }
13449                 mWindowManager.setAppFullscreen(token, true);
13450                 return translucentChanged;
13451             }
13452         } finally {
13453             Binder.restoreCallingIdentity(origId);
13454         }
13455     }
13456
13457     @Override
13458     public boolean convertToTranslucent(IBinder token, Bundle options) {
13459         final long origId = Binder.clearCallingIdentity();
13460         try {
13461             synchronized (this) {
13462                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13463                 if (r == null) {
13464                     return false;
13465                 }
13466                 final TaskRecord task = r.getTask();
13467                 int index = task.mActivities.lastIndexOf(r);
13468                 if (index > 0) {
13469                     ActivityRecord under = task.mActivities.get(index - 1);
13470                     under.returningOptions = ActivityOptions.fromBundle(options);
13471                 }
13472                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13473                 if (translucentChanged) {
13474                     r.getStack().convertActivityToTranslucent(r);
13475                 }
13476                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13477                 mWindowManager.setAppFullscreen(token, false);
13478                 return translucentChanged;
13479             }
13480         } finally {
13481             Binder.restoreCallingIdentity(origId);
13482         }
13483     }
13484
13485     @Override
13486     public Bundle getActivityOptions(IBinder token) {
13487         final long origId = Binder.clearCallingIdentity();
13488         try {
13489             synchronized (this) {
13490                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13491                 if (r != null) {
13492                     final ActivityOptions activityOptions = r.takeOptionsLocked();
13493                     return activityOptions == null ? null : activityOptions.toBundle();
13494                 }
13495                 return null;
13496             }
13497         } finally {
13498             Binder.restoreCallingIdentity(origId);
13499         }
13500     }
13501
13502     @Override
13503     public void setImmersive(IBinder token, boolean immersive) {
13504         synchronized(this) {
13505             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13506             if (r == null) {
13507                 throw new IllegalArgumentException();
13508             }
13509             r.immersive = immersive;
13510
13511             // update associated state if we're frontmost
13512             if (r == mStackSupervisor.getResumedActivityLocked()) {
13513                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13514                 applyUpdateLockStateLocked(r);
13515             }
13516         }
13517     }
13518
13519     @Override
13520     public boolean isImmersive(IBinder token) {
13521         synchronized (this) {
13522             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13523             if (r == null) {
13524                 throw new IllegalArgumentException();
13525             }
13526             return r.immersive;
13527         }
13528     }
13529
13530     @Override
13531     public void setVrThread(int tid) {
13532         enforceSystemHasVrFeature();
13533         synchronized (this) {
13534             synchronized (mPidsSelfLocked) {
13535                 final int pid = Binder.getCallingPid();
13536                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13537                 mVrController.setVrThreadLocked(tid, pid, proc);
13538             }
13539         }
13540     }
13541
13542     @Override
13543     public void setPersistentVrThread(int tid) {
13544         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13545             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13546                     + Binder.getCallingPid()
13547                     + ", uid=" + Binder.getCallingUid()
13548                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13549             Slog.w(TAG, msg);
13550             throw new SecurityException(msg);
13551         }
13552         enforceSystemHasVrFeature();
13553         synchronized (this) {
13554             synchronized (mPidsSelfLocked) {
13555                 final int pid = Binder.getCallingPid();
13556                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13557                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13558             }
13559         }
13560     }
13561
13562     /**
13563      * Schedule the given thread a normal scheduling priority.
13564      *
13565      * @param tid the tid of the thread to adjust the scheduling of.
13566      * @param suppressLogs {@code true} if any error logging should be disabled.
13567      *
13568      * @return {@code true} if this succeeded.
13569      */
13570     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13571         try {
13572             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13573             return true;
13574         } catch (IllegalArgumentException e) {
13575             if (!suppressLogs) {
13576                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13577             }
13578         } catch (SecurityException e) {
13579             if (!suppressLogs) {
13580                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13581             }
13582         }
13583         return false;
13584     }
13585
13586     /**
13587      * Schedule the given thread an FIFO scheduling priority.
13588      *
13589      * @param tid the tid of the thread to adjust the scheduling of.
13590      * @param suppressLogs {@code true} if any error logging should be disabled.
13591      *
13592      * @return {@code true} if this succeeded.
13593      */
13594     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13595         try {
13596             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13597             return true;
13598         } catch (IllegalArgumentException e) {
13599             if (!suppressLogs) {
13600                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13601             }
13602         } catch (SecurityException e) {
13603             if (!suppressLogs) {
13604                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13605             }
13606         }
13607         return false;
13608     }
13609
13610     /**
13611      * Check that we have the features required for VR-related API calls, and throw an exception if
13612      * not.
13613      */
13614     private void enforceSystemHasVrFeature() {
13615         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13616             throw new UnsupportedOperationException("VR mode not supported on this device!");
13617         }
13618     }
13619
13620     @Override
13621     public void setRenderThread(int tid) {
13622         synchronized (this) {
13623             ProcessRecord proc;
13624             int pid = Binder.getCallingPid();
13625             if (pid == Process.myPid()) {
13626                 demoteSystemServerRenderThread(tid);
13627                 return;
13628             }
13629             synchronized (mPidsSelfLocked) {
13630                 proc = mPidsSelfLocked.get(pid);
13631                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13632                     // ensure the tid belongs to the process
13633                     if (!isThreadInProcess(pid, tid)) {
13634                         throw new IllegalArgumentException(
13635                             "Render thread does not belong to process");
13636                     }
13637                     proc.renderThreadTid = tid;
13638                     if (DEBUG_OOM_ADJ) {
13639                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13640                     }
13641                     // promote to FIFO now
13642                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13643                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13644                         if (mUseFifoUiScheduling) {
13645                             setThreadScheduler(proc.renderThreadTid,
13646                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13647                         } else {
13648                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13649                         }
13650                     }
13651                 } else {
13652                     if (DEBUG_OOM_ADJ) {
13653                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13654                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13655                                mUseFifoUiScheduling);
13656                     }
13657                 }
13658             }
13659         }
13660     }
13661
13662     /**
13663      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13664      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13665      *
13666      * @param tid the tid of the RenderThread
13667      */
13668     private void demoteSystemServerRenderThread(int tid) {
13669         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13670     }
13671
13672     @Override
13673     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13674         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13675             throw new UnsupportedOperationException("VR mode not supported on this device!");
13676         }
13677
13678         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13679
13680         ActivityRecord r;
13681         synchronized (this) {
13682             r = ActivityRecord.isInStackLocked(token);
13683         }
13684
13685         if (r == null) {
13686             throw new IllegalArgumentException();
13687         }
13688
13689         int err;
13690         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13691                 VrManagerInternal.NO_ERROR) {
13692             return err;
13693         }
13694
13695         synchronized(this) {
13696             r.requestedVrComponent = (enabled) ? packageName : null;
13697
13698             // Update associated state if this activity is currently focused
13699             if (r == mStackSupervisor.getResumedActivityLocked()) {
13700                 applyUpdateVrModeLocked(r);
13701             }
13702             return 0;
13703         }
13704     }
13705
13706     @Override
13707     public boolean isVrModePackageEnabled(ComponentName packageName) {
13708         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13709             throw new UnsupportedOperationException("VR mode not supported on this device!");
13710         }
13711
13712         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13713
13714         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13715                 VrManagerInternal.NO_ERROR;
13716     }
13717
13718     public boolean isTopActivityImmersive() {
13719         enforceNotIsolatedCaller("startActivity");
13720         synchronized (this) {
13721             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13722             return (r != null) ? r.immersive : false;
13723         }
13724     }
13725
13726     /**
13727      * @return whether the system should disable UI modes incompatible with VR mode.
13728      */
13729     boolean shouldDisableNonVrUiLocked() {
13730         return mVrController.shouldDisableNonVrUiLocked();
13731     }
13732
13733     @Override
13734     public boolean isTopOfTask(IBinder token) {
13735         synchronized (this) {
13736             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13737             if (r == null) {
13738                 throw new IllegalArgumentException();
13739             }
13740             return r.getTask().getTopActivity() == r;
13741         }
13742     }
13743
13744     @Override
13745     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13746         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13747             String msg = "Permission Denial: setHasTopUi() from pid="
13748                     + Binder.getCallingPid()
13749                     + ", uid=" + Binder.getCallingUid()
13750                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13751             Slog.w(TAG, msg);
13752             throw new SecurityException(msg);
13753         }
13754         final int pid = Binder.getCallingPid();
13755         final long origId = Binder.clearCallingIdentity();
13756         try {
13757             synchronized (this) {
13758                 boolean changed = false;
13759                 ProcessRecord pr;
13760                 synchronized (mPidsSelfLocked) {
13761                     pr = mPidsSelfLocked.get(pid);
13762                     if (pr == null) {
13763                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13764                         return;
13765                     }
13766                     if (pr.hasTopUi != hasTopUi) {
13767                         if (DEBUG_OOM_ADJ) {
13768                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13769                         }
13770                         pr.hasTopUi = hasTopUi;
13771                         changed = true;
13772                     }
13773                 }
13774                 if (changed) {
13775                     updateOomAdjLocked(pr, true);
13776                 }
13777             }
13778         } finally {
13779             Binder.restoreCallingIdentity(origId);
13780         }
13781     }
13782
13783     public final void enterSafeMode() {
13784         synchronized(this) {
13785             // It only makes sense to do this before the system is ready
13786             // and started launching other packages.
13787             if (!mSystemReady) {
13788                 try {
13789                     AppGlobals.getPackageManager().enterSafeMode();
13790                 } catch (RemoteException e) {
13791                 }
13792             }
13793
13794             mSafeMode = true;
13795         }
13796     }
13797
13798     public final void showSafeModeOverlay() {
13799         View v = LayoutInflater.from(mContext).inflate(
13800                 com.android.internal.R.layout.safe_mode, null);
13801         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13802         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13803         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13804         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13805         lp.gravity = Gravity.BOTTOM | Gravity.START;
13806         lp.format = v.getBackground().getOpacity();
13807         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13808                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13809         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13810         ((WindowManager)mContext.getSystemService(
13811                 Context.WINDOW_SERVICE)).addView(v, lp);
13812     }
13813
13814     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13815         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13816             return;
13817         }
13818         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13819         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13820         synchronized (stats) {
13821             if (mBatteryStatsService.isOnBattery()) {
13822                 mBatteryStatsService.enforceCallingPermission();
13823                 int MY_UID = Binder.getCallingUid();
13824                 final int uid;
13825                 if (sender == null) {
13826                     uid = sourceUid;
13827                 } else {
13828                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13829                 }
13830                 BatteryStatsImpl.Uid.Pkg pkg =
13831                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13832                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13833                 pkg.noteWakeupAlarmLocked(tag);
13834             }
13835         }
13836     }
13837
13838     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13839         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13840             return;
13841         }
13842         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13843         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13844         synchronized (stats) {
13845             mBatteryStatsService.enforceCallingPermission();
13846             int MY_UID = Binder.getCallingUid();
13847             final int uid;
13848             if (sender == null) {
13849                 uid = sourceUid;
13850             } else {
13851                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13852             }
13853             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13854         }
13855     }
13856
13857     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13858         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13859             return;
13860         }
13861         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13862         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13863         synchronized (stats) {
13864             mBatteryStatsService.enforceCallingPermission();
13865             int MY_UID = Binder.getCallingUid();
13866             final int uid;
13867             if (sender == null) {
13868                 uid = sourceUid;
13869             } else {
13870                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13871             }
13872             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13873         }
13874     }
13875
13876     public boolean killPids(int[] pids, String pReason, boolean secure) {
13877         if (Binder.getCallingUid() != SYSTEM_UID) {
13878             throw new SecurityException("killPids only available to the system");
13879         }
13880         String reason = (pReason == null) ? "Unknown" : pReason;
13881         // XXX Note: don't acquire main activity lock here, because the window
13882         // manager calls in with its locks held.
13883
13884         boolean killed = false;
13885         synchronized (mPidsSelfLocked) {
13886             int worstType = 0;
13887             for (int i=0; i<pids.length; i++) {
13888                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13889                 if (proc != null) {
13890                     int type = proc.setAdj;
13891                     if (type > worstType) {
13892                         worstType = type;
13893                     }
13894                 }
13895             }
13896
13897             // If the worst oom_adj is somewhere in the cached proc LRU range,
13898             // then constrain it so we will kill all cached procs.
13899             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13900                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13901                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13902             }
13903
13904             // If this is not a secure call, don't let it kill processes that
13905             // are important.
13906             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13907                 worstType = ProcessList.SERVICE_ADJ;
13908             }
13909
13910             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13911             for (int i=0; i<pids.length; i++) {
13912                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13913                 if (proc == null) {
13914                     continue;
13915                 }
13916                 int adj = proc.setAdj;
13917                 if (adj >= worstType && !proc.killedByAm) {
13918                     proc.kill(reason, true);
13919                     killed = true;
13920                 }
13921             }
13922         }
13923         return killed;
13924     }
13925
13926     @Override
13927     public void killUid(int appId, int userId, String reason) {
13928         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13929         synchronized (this) {
13930             final long identity = Binder.clearCallingIdentity();
13931             try {
13932                 killPackageProcessesLocked(null, appId, userId,
13933                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13934                         reason != null ? reason : "kill uid");
13935             } finally {
13936                 Binder.restoreCallingIdentity(identity);
13937             }
13938         }
13939     }
13940
13941     @Override
13942     public boolean killProcessesBelowForeground(String reason) {
13943         if (Binder.getCallingUid() != SYSTEM_UID) {
13944             throw new SecurityException("killProcessesBelowForeground() only available to system");
13945         }
13946
13947         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13948     }
13949
13950     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13951         if (Binder.getCallingUid() != SYSTEM_UID) {
13952             throw new SecurityException("killProcessesBelowAdj() only available to system");
13953         }
13954
13955         boolean killed = false;
13956         synchronized (mPidsSelfLocked) {
13957             final int size = mPidsSelfLocked.size();
13958             for (int i = 0; i < size; i++) {
13959                 final int pid = mPidsSelfLocked.keyAt(i);
13960                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13961                 if (proc == null) continue;
13962
13963                 final int adj = proc.setAdj;
13964                 if (adj > belowAdj && !proc.killedByAm) {
13965                     proc.kill(reason, true);
13966                     killed = true;
13967                 }
13968             }
13969         }
13970         return killed;
13971     }
13972
13973     @Override
13974     public void hang(final IBinder who, boolean allowRestart) {
13975         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13976                 != PackageManager.PERMISSION_GRANTED) {
13977             throw new SecurityException("Requires permission "
13978                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13979         }
13980
13981         final IBinder.DeathRecipient death = new DeathRecipient() {
13982             @Override
13983             public void binderDied() {
13984                 synchronized (this) {
13985                     notifyAll();
13986                 }
13987             }
13988         };
13989
13990         try {
13991             who.linkToDeath(death, 0);
13992         } catch (RemoteException e) {
13993             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13994             return;
13995         }
13996
13997         synchronized (this) {
13998             Watchdog.getInstance().setAllowRestart(allowRestart);
13999             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
14000             synchronized (death) {
14001                 while (who.isBinderAlive()) {
14002                     try {
14003                         death.wait();
14004                     } catch (InterruptedException e) {
14005                     }
14006                 }
14007             }
14008             Watchdog.getInstance().setAllowRestart(true);
14009         }
14010     }
14011
14012     @Override
14013     public void restart() {
14014         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14015                 != PackageManager.PERMISSION_GRANTED) {
14016             throw new SecurityException("Requires permission "
14017                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14018         }
14019
14020         Log.i(TAG, "Sending shutdown broadcast...");
14021
14022         BroadcastReceiver br = new BroadcastReceiver() {
14023             @Override public void onReceive(Context context, Intent intent) {
14024                 // Now the broadcast is done, finish up the low-level shutdown.
14025                 Log.i(TAG, "Shutting down activity manager...");
14026                 shutdown(10000);
14027                 Log.i(TAG, "Shutdown complete, restarting!");
14028                 killProcess(myPid());
14029                 System.exit(10);
14030             }
14031         };
14032
14033         // First send the high-level shut down broadcast.
14034         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
14035         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14036         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
14037         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
14038         mContext.sendOrderedBroadcastAsUser(intent,
14039                 UserHandle.ALL, null, br, mHandler, 0, null, null);
14040         */
14041         br.onReceive(mContext, intent);
14042     }
14043
14044     private long getLowRamTimeSinceIdle(long now) {
14045         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
14046     }
14047
14048     @Override
14049     public void performIdleMaintenance() {
14050         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14051                 != PackageManager.PERMISSION_GRANTED) {
14052             throw new SecurityException("Requires permission "
14053                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14054         }
14055
14056         synchronized (this) {
14057             final long now = SystemClock.uptimeMillis();
14058             final long timeSinceLastIdle = now - mLastIdleTime;
14059             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
14060             mLastIdleTime = now;
14061             mLowRamTimeSinceLastIdle = 0;
14062             if (mLowRamStartTime != 0) {
14063                 mLowRamStartTime = now;
14064             }
14065
14066             StringBuilder sb = new StringBuilder(128);
14067             sb.append("Idle maintenance over ");
14068             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14069             sb.append(" low RAM for ");
14070             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14071             Slog.i(TAG, sb.toString());
14072
14073             // If at least 1/3 of our time since the last idle period has been spent
14074             // with RAM low, then we want to kill processes.
14075             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14076
14077             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14078                 ProcessRecord proc = mLruProcesses.get(i);
14079                 if (proc.notCachedSinceIdle) {
14080                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14081                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14082                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14083                         if (doKilling && proc.initialIdlePss != 0
14084                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14085                             sb = new StringBuilder(128);
14086                             sb.append("Kill");
14087                             sb.append(proc.processName);
14088                             sb.append(" in idle maint: pss=");
14089                             sb.append(proc.lastPss);
14090                             sb.append(", swapPss=");
14091                             sb.append(proc.lastSwapPss);
14092                             sb.append(", initialPss=");
14093                             sb.append(proc.initialIdlePss);
14094                             sb.append(", period=");
14095                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14096                             sb.append(", lowRamPeriod=");
14097                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14098                             Slog.wtfQuiet(TAG, sb.toString());
14099                             proc.kill("idle maint (pss " + proc.lastPss
14100                                     + " from " + proc.initialIdlePss + ")", true);
14101                         }
14102                     }
14103                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14104                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14105                     proc.notCachedSinceIdle = true;
14106                     proc.initialIdlePss = 0;
14107                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14108                             mTestPssMode, isSleepingLocked(), now);
14109                 }
14110             }
14111
14112             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14113             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14114         }
14115     }
14116
14117     @Override
14118     public void sendIdleJobTrigger() {
14119         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14120                 != PackageManager.PERMISSION_GRANTED) {
14121             throw new SecurityException("Requires permission "
14122                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14123         }
14124
14125         final long ident = Binder.clearCallingIdentity();
14126         try {
14127             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14128                     .setPackage("android")
14129                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14130             broadcastIntent(null, intent, null, null, 0, null, null, null,
14131                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14132         } finally {
14133             Binder.restoreCallingIdentity(ident);
14134         }
14135     }
14136
14137     private void retrieveSettings() {
14138         final ContentResolver resolver = mContext.getContentResolver();
14139         final boolean freeformWindowManagement =
14140                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14141                         || Settings.Global.getInt(
14142                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14143
14144         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14145         final boolean supportsPictureInPicture = supportsMultiWindow &&
14146                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14147         final boolean supportsSplitScreenMultiWindow =
14148                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14149         final boolean supportsMultiDisplay = mContext.getPackageManager()
14150                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14151         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14152         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14153         final boolean alwaysFinishActivities =
14154                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14155         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14156         final boolean forceResizable = Settings.Global.getInt(
14157                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14158         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14159                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14160         final boolean supportsLeanbackOnly =
14161                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14162
14163         // Transfer any global setting for forcing RTL layout, into a System Property
14164         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14165
14166         final Configuration configuration = new Configuration();
14167         Settings.System.getConfiguration(resolver, configuration);
14168         if (forceRtl) {
14169             // This will take care of setting the correct layout direction flags
14170             configuration.setLayoutDirection(configuration.locale);
14171         }
14172
14173         synchronized (this) {
14174             mDebugApp = mOrigDebugApp = debugApp;
14175             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14176             mAlwaysFinishActivities = alwaysFinishActivities;
14177             mSupportsLeanbackOnly = supportsLeanbackOnly;
14178             mForceResizableActivities = forceResizable;
14179             final boolean multiWindowFormEnabled = freeformWindowManagement
14180                     || supportsSplitScreenMultiWindow
14181                     || supportsPictureInPicture
14182                     || supportsMultiDisplay;
14183             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14184                 mSupportsMultiWindow = true;
14185                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14186                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14187                 mSupportsPictureInPicture = supportsPictureInPicture;
14188                 mSupportsMultiDisplay = supportsMultiDisplay;
14189             } else {
14190                 mSupportsMultiWindow = false;
14191                 mSupportsFreeformWindowManagement = false;
14192                 mSupportsSplitScreenMultiWindow = false;
14193                 mSupportsPictureInPicture = false;
14194                 mSupportsMultiDisplay = false;
14195             }
14196             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14197             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14198             // This happens before any activities are started, so we can change global configuration
14199             // in-place.
14200             updateConfigurationLocked(configuration, null, true);
14201             final Configuration globalConfig = getGlobalConfiguration();
14202             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14203
14204             // Load resources only after the current configuration has been set.
14205             final Resources res = mContext.getResources();
14206             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14207             mThumbnailWidth = res.getDimensionPixelSize(
14208                     com.android.internal.R.dimen.thumbnail_width);
14209             mThumbnailHeight = res.getDimensionPixelSize(
14210                     com.android.internal.R.dimen.thumbnail_height);
14211             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14212                     com.android.internal.R.string.config_appsNotReportingCrashes));
14213             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14214                     com.android.internal.R.bool.config_customUserSwitchUi);
14215             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14216                 mFullscreenThumbnailScale = (float) res
14217                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14218                     (float) globalConfig.screenWidthDp;
14219             } else {
14220                 mFullscreenThumbnailScale = res.getFraction(
14221                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14222             }
14223             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14224         }
14225     }
14226
14227     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14228         traceLog.traceBegin("PhaseActivityManagerReady");
14229         synchronized(this) {
14230             if (mSystemReady) {
14231                 // If we're done calling all the receivers, run the next "boot phase" passed in
14232                 // by the SystemServer
14233                 if (goingCallback != null) {
14234                     goingCallback.run();
14235                 }
14236                 return;
14237             }
14238
14239             mLocalDeviceIdleController
14240                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14241             mAssistUtils = new AssistUtils(mContext);
14242             mVrController.onSystemReady();
14243             // Make sure we have the current profile info, since it is needed for security checks.
14244             mUserController.onSystemReady();
14245             mRecentTasks.onSystemReadyLocked();
14246             mAppOpsService.systemReady();
14247             mSystemReady = true;
14248         }
14249
14250         try {
14251             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14252                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14253                     .getSerial();
14254         } catch (RemoteException e) {}
14255
14256         ArrayList<ProcessRecord> procsToKill = null;
14257         synchronized(mPidsSelfLocked) {
14258             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14259                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14260                 if (!isAllowedWhileBooting(proc.info)){
14261                     if (procsToKill == null) {
14262                         procsToKill = new ArrayList<ProcessRecord>();
14263                     }
14264                     procsToKill.add(proc);
14265                 }
14266             }
14267         }
14268
14269         synchronized(this) {
14270             if (procsToKill != null) {
14271                 for (int i=procsToKill.size()-1; i>=0; i--) {
14272                     ProcessRecord proc = procsToKill.get(i);
14273                     Slog.i(TAG, "Removing system update proc: " + proc);
14274                     removeProcessLocked(proc, true, false, "system update done");
14275                 }
14276             }
14277
14278             // Now that we have cleaned up any update processes, we
14279             // are ready to start launching real processes and know that
14280             // we won't trample on them any more.
14281             mProcessesReady = true;
14282         }
14283
14284         Slog.i(TAG, "System now ready");
14285         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14286             SystemClock.uptimeMillis());
14287
14288         synchronized(this) {
14289             // Make sure we have no pre-ready processes sitting around.
14290
14291             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14292                 ResolveInfo ri = mContext.getPackageManager()
14293                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14294                                 STOCK_PM_FLAGS);
14295                 CharSequence errorMsg = null;
14296                 if (ri != null) {
14297                     ActivityInfo ai = ri.activityInfo;
14298                     ApplicationInfo app = ai.applicationInfo;
14299                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14300                         mTopAction = Intent.ACTION_FACTORY_TEST;
14301                         mTopData = null;
14302                         mTopComponent = new ComponentName(app.packageName,
14303                                 ai.name);
14304                     } else {
14305                         errorMsg = mContext.getResources().getText(
14306                                 com.android.internal.R.string.factorytest_not_system);
14307                     }
14308                 } else {
14309                     errorMsg = mContext.getResources().getText(
14310                             com.android.internal.R.string.factorytest_no_action);
14311                 }
14312                 if (errorMsg != null) {
14313                     mTopAction = null;
14314                     mTopData = null;
14315                     mTopComponent = null;
14316                     Message msg = Message.obtain();
14317                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14318                     msg.getData().putCharSequence("msg", errorMsg);
14319                     mUiHandler.sendMessage(msg);
14320                 }
14321             }
14322         }
14323
14324         retrieveSettings();
14325         final int currentUserId;
14326         synchronized (this) {
14327             currentUserId = mUserController.getCurrentUserIdLocked();
14328             readGrantedUriPermissionsLocked();
14329         }
14330
14331         if (goingCallback != null) goingCallback.run();
14332         traceLog.traceBegin("ActivityManagerStartApps");
14333         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14334                 Integer.toString(currentUserId), currentUserId);
14335         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14336                 Integer.toString(currentUserId), currentUserId);
14337         mSystemServiceManager.startUser(currentUserId);
14338
14339         synchronized (this) {
14340             // Only start up encryption-aware persistent apps; once user is
14341             // unlocked we'll come back around and start unaware apps
14342             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14343
14344             // Start up initial activity.
14345             mBooting = true;
14346             // Enable home activity for system user, so that the system can always boot. We don't
14347             // do this when the system user is not setup since the setup wizard should be the one
14348             // to handle home activity in this case.
14349             if (UserManager.isSplitSystemUser() &&
14350                     Settings.Secure.getInt(mContext.getContentResolver(),
14351                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14352                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14353                 try {
14354                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14355                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14356                             UserHandle.USER_SYSTEM);
14357                 } catch (RemoteException e) {
14358                     throw e.rethrowAsRuntimeException();
14359                 }
14360             }
14361             startHomeActivityLocked(currentUserId, "systemReady");
14362
14363             try {
14364                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14365                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14366                             + " data partition or your device will be unstable.");
14367                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14368                 }
14369             } catch (RemoteException e) {
14370             }
14371
14372             if (!Build.isBuildConsistent()) {
14373                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14374                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14375             }
14376
14377             long ident = Binder.clearCallingIdentity();
14378             try {
14379                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14380                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14381                         | Intent.FLAG_RECEIVER_FOREGROUND);
14382                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14383                 broadcastIntentLocked(null, null, intent,
14384                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14385                         null, false, false, MY_PID, SYSTEM_UID,
14386                         currentUserId);
14387                 intent = new Intent(Intent.ACTION_USER_STARTING);
14388                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14389                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14390                 broadcastIntentLocked(null, null, intent,
14391                         null, new IIntentReceiver.Stub() {
14392                             @Override
14393                             public void performReceive(Intent intent, int resultCode, String data,
14394                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14395                                     throws RemoteException {
14396                             }
14397                         }, 0, null, null,
14398                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14399                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14400             } catch (Throwable t) {
14401                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14402             } finally {
14403                 Binder.restoreCallingIdentity(ident);
14404             }
14405             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14406             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14407             traceLog.traceEnd(); // ActivityManagerStartApps
14408             traceLog.traceEnd(); // PhaseActivityManagerReady
14409         }
14410     }
14411
14412     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14413         synchronized (this) {
14414             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14415         }
14416     }
14417
14418     void skipCurrentReceiverLocked(ProcessRecord app) {
14419         for (BroadcastQueue queue : mBroadcastQueues) {
14420             queue.skipCurrentReceiverLocked(app);
14421         }
14422     }
14423
14424     /**
14425      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14426      * The application process will exit immediately after this call returns.
14427      * @param app object of the crashing app, null for the system server
14428      * @param crashInfo describing the exception
14429      */
14430     public void handleApplicationCrash(IBinder app,
14431             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14432         ProcessRecord r = findAppProcess(app, "Crash");
14433         final String processName = app == null ? "system_server"
14434                 : (r == null ? "unknown" : r.processName);
14435
14436         handleApplicationCrashInner("crash", r, processName, crashInfo);
14437     }
14438
14439     /* Native crash reporting uses this inner version because it needs to be somewhat
14440      * decoupled from the AM-managed cleanup lifecycle
14441      */
14442     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14443             ApplicationErrorReport.CrashInfo crashInfo) {
14444         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14445                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14446                 r == null ? -1 : r.info.flags,
14447                 crashInfo.exceptionClassName,
14448                 crashInfo.exceptionMessage,
14449                 crashInfo.throwFileName,
14450                 crashInfo.throwLineNumber);
14451
14452         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14453
14454         mAppErrors.crashApplication(r, crashInfo);
14455     }
14456
14457     public void handleApplicationStrictModeViolation(
14458             IBinder app,
14459             int violationMask,
14460             StrictMode.ViolationInfo info) {
14461         ProcessRecord r = findAppProcess(app, "StrictMode");
14462         if (r == null) {
14463             return;
14464         }
14465
14466         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14467             Integer stackFingerprint = info.hashCode();
14468             boolean logIt = true;
14469             synchronized (mAlreadyLoggedViolatedStacks) {
14470                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14471                     logIt = false;
14472                     // TODO: sub-sample into EventLog for these, with
14473                     // the info.durationMillis?  Then we'd get
14474                     // the relative pain numbers, without logging all
14475                     // the stack traces repeatedly.  We'd want to do
14476                     // likewise in the client code, which also does
14477                     // dup suppression, before the Binder call.
14478                 } else {
14479                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14480                         mAlreadyLoggedViolatedStacks.clear();
14481                     }
14482                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14483                 }
14484             }
14485             if (logIt) {
14486                 logStrictModeViolationToDropBox(r, info);
14487             }
14488         }
14489
14490         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14491             AppErrorResult result = new AppErrorResult();
14492             synchronized (this) {
14493                 final long origId = Binder.clearCallingIdentity();
14494
14495                 Message msg = Message.obtain();
14496                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14497                 HashMap<String, Object> data = new HashMap<String, Object>();
14498                 data.put("result", result);
14499                 data.put("app", r);
14500                 data.put("violationMask", violationMask);
14501                 data.put("info", info);
14502                 msg.obj = data;
14503                 mUiHandler.sendMessage(msg);
14504
14505                 Binder.restoreCallingIdentity(origId);
14506             }
14507             int res = result.get();
14508             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14509         }
14510     }
14511
14512     // Depending on the policy in effect, there could be a bunch of
14513     // these in quick succession so we try to batch these together to
14514     // minimize disk writes, number of dropbox entries, and maximize
14515     // compression, by having more fewer, larger records.
14516     private void logStrictModeViolationToDropBox(
14517             ProcessRecord process,
14518             StrictMode.ViolationInfo info) {
14519         if (info == null) {
14520             return;
14521         }
14522         final boolean isSystemApp = process == null ||
14523                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14524                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14525         final String processName = process == null ? "unknown" : process.processName;
14526         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14527         final DropBoxManager dbox = (DropBoxManager)
14528                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14529
14530         // Exit early if the dropbox isn't configured to accept this report type.
14531         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14532
14533         boolean bufferWasEmpty;
14534         boolean needsFlush;
14535         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14536         synchronized (sb) {
14537             bufferWasEmpty = sb.length() == 0;
14538             appendDropBoxProcessHeaders(process, processName, sb);
14539             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14540             sb.append("System-App: ").append(isSystemApp).append("\n");
14541             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14542             if (info.violationNumThisLoop != 0) {
14543                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14544             }
14545             if (info.numAnimationsRunning != 0) {
14546                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14547             }
14548             if (info.broadcastIntentAction != null) {
14549                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14550             }
14551             if (info.durationMillis != -1) {
14552                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14553             }
14554             if (info.numInstances != -1) {
14555                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14556             }
14557             if (info.tags != null) {
14558                 for (String tag : info.tags) {
14559                     sb.append("Span-Tag: ").append(tag).append("\n");
14560                 }
14561             }
14562             sb.append("\n");
14563             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14564                 sb.append(info.crashInfo.stackTrace);
14565                 sb.append("\n");
14566             }
14567             if (info.message != null) {
14568                 sb.append(info.message);
14569                 sb.append("\n");
14570             }
14571
14572             // Only buffer up to ~64k.  Various logging bits truncate
14573             // things at 128k.
14574             needsFlush = (sb.length() > 64 * 1024);
14575         }
14576
14577         // Flush immediately if the buffer's grown too large, or this
14578         // is a non-system app.  Non-system apps are isolated with a
14579         // different tag & policy and not batched.
14580         //
14581         // Batching is useful during internal testing with
14582         // StrictMode settings turned up high.  Without batching,
14583         // thousands of separate files could be created on boot.
14584         if (!isSystemApp || needsFlush) {
14585             new Thread("Error dump: " + dropboxTag) {
14586                 @Override
14587                 public void run() {
14588                     String report;
14589                     synchronized (sb) {
14590                         report = sb.toString();
14591                         sb.delete(0, sb.length());
14592                         sb.trimToSize();
14593                     }
14594                     if (report.length() != 0) {
14595                         dbox.addText(dropboxTag, report);
14596                     }
14597                 }
14598             }.start();
14599             return;
14600         }
14601
14602         // System app batching:
14603         if (!bufferWasEmpty) {
14604             // An existing dropbox-writing thread is outstanding, so
14605             // we don't need to start it up.  The existing thread will
14606             // catch the buffer appends we just did.
14607             return;
14608         }
14609
14610         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14611         // (After this point, we shouldn't access AMS internal data structures.)
14612         new Thread("Error dump: " + dropboxTag) {
14613             @Override
14614             public void run() {
14615                 // 5 second sleep to let stacks arrive and be batched together
14616                 try {
14617                     Thread.sleep(5000);  // 5 seconds
14618                 } catch (InterruptedException e) {}
14619
14620                 String errorReport;
14621                 synchronized (mStrictModeBuffer) {
14622                     errorReport = mStrictModeBuffer.toString();
14623                     if (errorReport.length() == 0) {
14624                         return;
14625                     }
14626                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14627                     mStrictModeBuffer.trimToSize();
14628                 }
14629                 dbox.addText(dropboxTag, errorReport);
14630             }
14631         }.start();
14632     }
14633
14634     /**
14635      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14636      * @param app object of the crashing app, null for the system server
14637      * @param tag reported by the caller
14638      * @param system whether this wtf is coming from the system
14639      * @param crashInfo describing the context of the error
14640      * @return true if the process should exit immediately (WTF is fatal)
14641      */
14642     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14643             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14644         final int callingUid = Binder.getCallingUid();
14645         final int callingPid = Binder.getCallingPid();
14646
14647         if (system) {
14648             // If this is coming from the system, we could very well have low-level
14649             // system locks held, so we want to do this all asynchronously.  And we
14650             // never want this to become fatal, so there is that too.
14651             mHandler.post(new Runnable() {
14652                 @Override public void run() {
14653                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14654                 }
14655             });
14656             return false;
14657         }
14658
14659         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14660                 crashInfo);
14661
14662         final boolean isFatal = Build.IS_ENG || Settings.Global
14663                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14664         final boolean isSystem = (r == null) || r.persistent;
14665
14666         if (isFatal && !isSystem) {
14667             mAppErrors.crashApplication(r, crashInfo);
14668             return true;
14669         } else {
14670             return false;
14671         }
14672     }
14673
14674     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14675             final ApplicationErrorReport.CrashInfo crashInfo) {
14676         final ProcessRecord r = findAppProcess(app, "WTF");
14677         final String processName = app == null ? "system_server"
14678                 : (r == null ? "unknown" : r.processName);
14679
14680         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14681                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14682
14683         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14684
14685         return r;
14686     }
14687
14688     /**
14689      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14690      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14691      */
14692     private ProcessRecord findAppProcess(IBinder app, String reason) {
14693         if (app == null) {
14694             return null;
14695         }
14696
14697         synchronized (this) {
14698             final int NP = mProcessNames.getMap().size();
14699             for (int ip=0; ip<NP; ip++) {
14700                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14701                 final int NA = apps.size();
14702                 for (int ia=0; ia<NA; ia++) {
14703                     ProcessRecord p = apps.valueAt(ia);
14704                     if (p.thread != null && p.thread.asBinder() == app) {
14705                         return p;
14706                     }
14707                 }
14708             }
14709
14710             Slog.w(TAG, "Can't find mystery application for " + reason
14711                     + " from pid=" + Binder.getCallingPid()
14712                     + " uid=" + Binder.getCallingUid() + ": " + app);
14713             return null;
14714         }
14715     }
14716
14717     /**
14718      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14719      * to append various headers to the dropbox log text.
14720      */
14721     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14722             StringBuilder sb) {
14723         // Watchdog thread ends up invoking this function (with
14724         // a null ProcessRecord) to add the stack file to dropbox.
14725         // Do not acquire a lock on this (am) in such cases, as it
14726         // could cause a potential deadlock, if and when watchdog
14727         // is invoked due to unavailability of lock on am and it
14728         // would prevent watchdog from killing system_server.
14729         if (process == null) {
14730             sb.append("Process: ").append(processName).append("\n");
14731             return;
14732         }
14733         // Note: ProcessRecord 'process' is guarded by the service
14734         // instance.  (notably process.pkgList, which could otherwise change
14735         // concurrently during execution of this method)
14736         synchronized (this) {
14737             sb.append("Process: ").append(processName).append("\n");
14738             sb.append("PID: ").append(process.pid).append("\n");
14739             int flags = process.info.flags;
14740             IPackageManager pm = AppGlobals.getPackageManager();
14741             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14742             for (int ip=0; ip<process.pkgList.size(); ip++) {
14743                 String pkg = process.pkgList.keyAt(ip);
14744                 sb.append("Package: ").append(pkg);
14745                 try {
14746                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14747                     if (pi != null) {
14748                         sb.append(" v").append(pi.versionCode);
14749                         if (pi.versionName != null) {
14750                             sb.append(" (").append(pi.versionName).append(")");
14751                         }
14752                     }
14753                 } catch (RemoteException e) {
14754                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14755                 }
14756                 sb.append("\n");
14757             }
14758             if (process.info.isInstantApp()) {
14759                 sb.append("Instant-App: true\n");
14760             }
14761         }
14762     }
14763
14764     private static String processClass(ProcessRecord process) {
14765         if (process == null || process.pid == MY_PID) {
14766             return "system_server";
14767         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14768             return "system_app";
14769         } else {
14770             return "data_app";
14771         }
14772     }
14773
14774     private volatile long mWtfClusterStart;
14775     private volatile int mWtfClusterCount;
14776
14777     /**
14778      * Write a description of an error (crash, WTF, ANR) to the drop box.
14779      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14780      * @param process which caused the error, null means the system server
14781      * @param activity which triggered the error, null if unknown
14782      * @param parent activity related to the error, null if unknown
14783      * @param subject line related to the error, null if absent
14784      * @param report in long form describing the error, null if absent
14785      * @param dataFile text file to include in the report, null if none
14786      * @param crashInfo giving an application stack trace, null if absent
14787      */
14788     public void addErrorToDropBox(String eventType,
14789             ProcessRecord process, String processName, ActivityRecord activity,
14790             ActivityRecord parent, String subject,
14791             final String report, final File dataFile,
14792             final ApplicationErrorReport.CrashInfo crashInfo) {
14793         // NOTE -- this must never acquire the ActivityManagerService lock,
14794         // otherwise the watchdog may be prevented from resetting the system.
14795
14796         // Bail early if not published yet
14797         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14798         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14799
14800         // Exit early if the dropbox isn't configured to accept this report type.
14801         final String dropboxTag = processClass(process) + "_" + eventType;
14802         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14803
14804         // Rate-limit how often we're willing to do the heavy lifting below to
14805         // collect and record logs; currently 5 logs per 10 second period.
14806         final long now = SystemClock.elapsedRealtime();
14807         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14808             mWtfClusterStart = now;
14809             mWtfClusterCount = 1;
14810         } else {
14811             if (mWtfClusterCount++ >= 5) return;
14812         }
14813
14814         final StringBuilder sb = new StringBuilder(1024);
14815         appendDropBoxProcessHeaders(process, processName, sb);
14816         if (process != null) {
14817             sb.append("Foreground: ")
14818                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14819                     .append("\n");
14820         }
14821         if (activity != null) {
14822             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14823         }
14824         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14825             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14826         }
14827         if (parent != null && parent != activity) {
14828             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14829         }
14830         if (subject != null) {
14831             sb.append("Subject: ").append(subject).append("\n");
14832         }
14833         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14834         if (Debug.isDebuggerConnected()) {
14835             sb.append("Debugger: Connected\n");
14836         }
14837         sb.append("\n");
14838
14839         // Do the rest in a worker thread to avoid blocking the caller on I/O
14840         // (After this point, we shouldn't access AMS internal data structures.)
14841         Thread worker = new Thread("Error dump: " + dropboxTag) {
14842             @Override
14843             public void run() {
14844                 if (report != null) {
14845                     sb.append(report);
14846                 }
14847
14848                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14849                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14850                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14851                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14852
14853                 if (dataFile != null && maxDataFileSize > 0) {
14854                     try {
14855                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14856                                     "\n\n[[TRUNCATED]]"));
14857                     } catch (IOException e) {
14858                         Slog.e(TAG, "Error reading " + dataFile, e);
14859                     }
14860                 }
14861                 if (crashInfo != null && crashInfo.stackTrace != null) {
14862                     sb.append(crashInfo.stackTrace);
14863                 }
14864
14865                 if (lines > 0) {
14866                     sb.append("\n");
14867
14868                     // Merge several logcat streams, and take the last N lines
14869                     InputStreamReader input = null;
14870                     try {
14871                         java.lang.Process logcat = new ProcessBuilder(
14872                                 "/system/bin/timeout", "-k", "15s", "10s",
14873                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14874                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14875                                         .redirectErrorStream(true).start();
14876
14877                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14878                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14879                         input = new InputStreamReader(logcat.getInputStream());
14880
14881                         int num;
14882                         char[] buf = new char[8192];
14883                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14884                     } catch (IOException e) {
14885                         Slog.e(TAG, "Error running logcat", e);
14886                     } finally {
14887                         if (input != null) try { input.close(); } catch (IOException e) {}
14888                     }
14889                 }
14890
14891                 dbox.addText(dropboxTag, sb.toString());
14892             }
14893         };
14894
14895         if (process == null) {
14896             // If process is null, we are being called from some internal code
14897             // and may be about to die -- run this synchronously.
14898             worker.run();
14899         } else {
14900             worker.start();
14901         }
14902     }
14903
14904     @Override
14905     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14906         enforceNotIsolatedCaller("getProcessesInErrorState");
14907         // assume our apps are happy - lazy create the list
14908         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14909
14910         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14911                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14912         int userId = UserHandle.getUserId(Binder.getCallingUid());
14913
14914         synchronized (this) {
14915
14916             // iterate across all processes
14917             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14918                 ProcessRecord app = mLruProcesses.get(i);
14919                 if (!allUsers && app.userId != userId) {
14920                     continue;
14921                 }
14922                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14923                     // This one's in trouble, so we'll generate a report for it
14924                     // crashes are higher priority (in case there's a crash *and* an anr)
14925                     ActivityManager.ProcessErrorStateInfo report = null;
14926                     if (app.crashing) {
14927                         report = app.crashingReport;
14928                     } else if (app.notResponding) {
14929                         report = app.notRespondingReport;
14930                     }
14931
14932                     if (report != null) {
14933                         if (errList == null) {
14934                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14935                         }
14936                         errList.add(report);
14937                     } else {
14938                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14939                                 " crashing = " + app.crashing +
14940                                 " notResponding = " + app.notResponding);
14941                     }
14942                 }
14943             }
14944         }
14945
14946         return errList;
14947     }
14948
14949     static int procStateToImportance(int procState, int memAdj,
14950             ActivityManager.RunningAppProcessInfo currApp,
14951             int clientTargetSdk) {
14952         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14953                 procState, clientTargetSdk);
14954         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14955             currApp.lru = memAdj;
14956         } else {
14957             currApp.lru = 0;
14958         }
14959         return imp;
14960     }
14961
14962     private void fillInProcMemInfo(ProcessRecord app,
14963             ActivityManager.RunningAppProcessInfo outInfo,
14964             int clientTargetSdk) {
14965         outInfo.pid = app.pid;
14966         outInfo.uid = app.info.uid;
14967         if (mHeavyWeightProcess == app) {
14968             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14969         }
14970         if (app.persistent) {
14971             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14972         }
14973         if (app.activities.size() > 0) {
14974             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14975         }
14976         outInfo.lastTrimLevel = app.trimMemoryLevel;
14977         int adj = app.curAdj;
14978         int procState = app.curProcState;
14979         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14980         outInfo.importanceReasonCode = app.adjTypeCode;
14981         outInfo.processState = app.curProcState;
14982     }
14983
14984     @Override
14985     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14986         enforceNotIsolatedCaller("getRunningAppProcesses");
14987
14988         final int callingUid = Binder.getCallingUid();
14989         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14990
14991         // Lazy instantiation of list
14992         List<ActivityManager.RunningAppProcessInfo> runList = null;
14993         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14994                 callingUid) == PackageManager.PERMISSION_GRANTED;
14995         final int userId = UserHandle.getUserId(callingUid);
14996         final boolean allUids = isGetTasksAllowed(
14997                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14998
14999         synchronized (this) {
15000             // Iterate across all processes
15001             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15002                 ProcessRecord app = mLruProcesses.get(i);
15003                 if ((!allUsers && app.userId != userId)
15004                         || (!allUids && app.uid != callingUid)) {
15005                     continue;
15006                 }
15007                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
15008                     // Generate process state info for running application
15009                     ActivityManager.RunningAppProcessInfo currApp =
15010                         new ActivityManager.RunningAppProcessInfo(app.processName,
15011                                 app.pid, app.getPackageList());
15012                     fillInProcMemInfo(app, currApp, clientTargetSdk);
15013                     if (app.adjSource instanceof ProcessRecord) {
15014                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
15015                         currApp.importanceReasonImportance =
15016                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
15017                                         app.adjSourceProcState);
15018                     } else if (app.adjSource instanceof ActivityRecord) {
15019                         ActivityRecord r = (ActivityRecord)app.adjSource;
15020                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
15021                     }
15022                     if (app.adjTarget instanceof ComponentName) {
15023                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
15024                     }
15025                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
15026                     //        + " lru=" + currApp.lru);
15027                     if (runList == null) {
15028                         runList = new ArrayList<>();
15029                     }
15030                     runList.add(currApp);
15031                 }
15032             }
15033         }
15034         return runList;
15035     }
15036
15037     @Override
15038     public List<ApplicationInfo> getRunningExternalApplications() {
15039         enforceNotIsolatedCaller("getRunningExternalApplications");
15040         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
15041         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
15042         if (runningApps != null && runningApps.size() > 0) {
15043             Set<String> extList = new HashSet<String>();
15044             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
15045                 if (app.pkgList != null) {
15046                     for (String pkg : app.pkgList) {
15047                         extList.add(pkg);
15048                     }
15049                 }
15050             }
15051             IPackageManager pm = AppGlobals.getPackageManager();
15052             for (String pkg : extList) {
15053                 try {
15054                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
15055                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
15056                         retList.add(info);
15057                     }
15058                 } catch (RemoteException e) {
15059                 }
15060             }
15061         }
15062         return retList;
15063     }
15064
15065     @Override
15066     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15067         enforceNotIsolatedCaller("getMyMemoryState");
15068
15069         final int callingUid = Binder.getCallingUid();
15070         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15071
15072         synchronized (this) {
15073             ProcessRecord proc;
15074             synchronized (mPidsSelfLocked) {
15075                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15076             }
15077             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15078         }
15079     }
15080
15081     @Override
15082     public int getMemoryTrimLevel() {
15083         enforceNotIsolatedCaller("getMyMemoryState");
15084         synchronized (this) {
15085             return mLastMemoryLevel;
15086         }
15087     }
15088
15089     @Override
15090     public void onShellCommand(FileDescriptor in, FileDescriptor out,
15091             FileDescriptor err, String[] args, ShellCallback callback,
15092             ResultReceiver resultReceiver) {
15093         (new ActivityManagerShellCommand(this, false)).exec(
15094                 this, in, out, err, args, callback, resultReceiver);
15095     }
15096
15097     SleepToken acquireSleepToken(String tag, int displayId) {
15098         synchronized (this) {
15099             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15100             updateSleepIfNeededLocked();
15101             return token;
15102         }
15103     }
15104
15105     @Override
15106     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15107         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15108
15109         boolean dumpAll = false;
15110         boolean dumpClient = false;
15111         boolean dumpCheckin = false;
15112         boolean dumpCheckinFormat = false;
15113         boolean dumpVisibleStacksOnly = false;
15114         boolean dumpFocusedStackOnly = false;
15115         String dumpPackage = null;
15116
15117         int opti = 0;
15118         while (opti < args.length) {
15119             String opt = args[opti];
15120             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15121                 break;
15122             }
15123             opti++;
15124             if ("-a".equals(opt)) {
15125                 dumpAll = true;
15126             } else if ("-c".equals(opt)) {
15127                 dumpClient = true;
15128             } else if ("-v".equals(opt)) {
15129                 dumpVisibleStacksOnly = true;
15130             } else if ("-f".equals(opt)) {
15131                 dumpFocusedStackOnly = true;
15132             } else if ("-p".equals(opt)) {
15133                 if (opti < args.length) {
15134                     dumpPackage = args[opti];
15135                     opti++;
15136                 } else {
15137                     pw.println("Error: -p option requires package argument");
15138                     return;
15139                 }
15140                 dumpClient = true;
15141             } else if ("--checkin".equals(opt)) {
15142                 dumpCheckin = dumpCheckinFormat = true;
15143             } else if ("-C".equals(opt)) {
15144                 dumpCheckinFormat = true;
15145             } else if ("-h".equals(opt)) {
15146                 ActivityManagerShellCommand.dumpHelp(pw, true);
15147                 return;
15148             } else {
15149                 pw.println("Unknown argument: " + opt + "; use -h for help");
15150             }
15151         }
15152
15153         long origId = Binder.clearCallingIdentity();
15154         boolean more = false;
15155         // Is the caller requesting to dump a particular piece of data?
15156         if (opti < args.length) {
15157             String cmd = args[opti];
15158             opti++;
15159             if ("activities".equals(cmd) || "a".equals(cmd)) {
15160                 synchronized (this) {
15161                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15162                 }
15163             } else if ("lastanr".equals(cmd)) {
15164                 synchronized (this) {
15165                     dumpLastANRLocked(pw);
15166                 }
15167             } else if ("starter".equals(cmd)) {
15168                 synchronized (this) {
15169                     dumpActivityStarterLocked(pw, dumpPackage);
15170                 }
15171             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15172                 synchronized (this) {
15173                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15174                 }
15175             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15176                 String[] newArgs;
15177                 String name;
15178                 if (opti >= args.length) {
15179                     name = null;
15180                     newArgs = EMPTY_STRING_ARRAY;
15181                 } else {
15182                     dumpPackage = args[opti];
15183                     opti++;
15184                     newArgs = new String[args.length - opti];
15185                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15186                             args.length - opti);
15187                 }
15188                 synchronized (this) {
15189                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15190                 }
15191             } else if ("broadcast-stats".equals(cmd)) {
15192                 String[] newArgs;
15193                 String name;
15194                 if (opti >= args.length) {
15195                     name = null;
15196                     newArgs = EMPTY_STRING_ARRAY;
15197                 } else {
15198                     dumpPackage = args[opti];
15199                     opti++;
15200                     newArgs = new String[args.length - opti];
15201                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15202                             args.length - opti);
15203                 }
15204                 synchronized (this) {
15205                     if (dumpCheckinFormat) {
15206                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15207                                 dumpPackage);
15208                     } else {
15209                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15210                     }
15211                 }
15212             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15213                 String[] newArgs;
15214                 String name;
15215                 if (opti >= args.length) {
15216                     name = null;
15217                     newArgs = EMPTY_STRING_ARRAY;
15218                 } else {
15219                     dumpPackage = args[opti];
15220                     opti++;
15221                     newArgs = new String[args.length - opti];
15222                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15223                             args.length - opti);
15224                 }
15225                 synchronized (this) {
15226                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15227                 }
15228             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15229                 String[] newArgs;
15230                 String name;
15231                 if (opti >= args.length) {
15232                     name = null;
15233                     newArgs = EMPTY_STRING_ARRAY;
15234                 } else {
15235                     dumpPackage = args[opti];
15236                     opti++;
15237                     newArgs = new String[args.length - opti];
15238                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15239                             args.length - opti);
15240                 }
15241                 synchronized (this) {
15242                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15243                 }
15244             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15245                 synchronized (this) {
15246                     dumpOomLocked(fd, pw, args, opti, true);
15247                 }
15248             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15249                 synchronized (this) {
15250                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15251                 }
15252             } else if ("provider".equals(cmd)) {
15253                 String[] newArgs;
15254                 String name;
15255                 if (opti >= args.length) {
15256                     name = null;
15257                     newArgs = EMPTY_STRING_ARRAY;
15258                 } else {
15259                     name = args[opti];
15260                     opti++;
15261                     newArgs = new String[args.length - opti];
15262                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15263                 }
15264                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15265                     pw.println("No providers match: " + name);
15266                     pw.println("Use -h for help.");
15267                 }
15268             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15269                 synchronized (this) {
15270                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15271                 }
15272             } else if ("service".equals(cmd)) {
15273                 String[] newArgs;
15274                 String name;
15275                 if (opti >= args.length) {
15276                     name = null;
15277                     newArgs = EMPTY_STRING_ARRAY;
15278                 } else {
15279                     name = args[opti];
15280                     opti++;
15281                     newArgs = new String[args.length - opti];
15282                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15283                             args.length - opti);
15284                 }
15285                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15286                     pw.println("No services match: " + name);
15287                     pw.println("Use -h for help.");
15288                 }
15289             } else if ("package".equals(cmd)) {
15290                 String[] newArgs;
15291                 if (opti >= args.length) {
15292                     pw.println("package: no package name specified");
15293                     pw.println("Use -h for help.");
15294                 } else {
15295                     dumpPackage = args[opti];
15296                     opti++;
15297                     newArgs = new String[args.length - opti];
15298                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15299                             args.length - opti);
15300                     args = newArgs;
15301                     opti = 0;
15302                     more = true;
15303                 }
15304             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15305                 synchronized (this) {
15306                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15307                 }
15308             } else if ("settings".equals(cmd)) {
15309                 synchronized (this) {
15310                     mConstants.dump(pw);
15311                 }
15312             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15313                 if (dumpClient) {
15314                     ActiveServices.ServiceDumper dumper;
15315                     synchronized (this) {
15316                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15317                                 dumpPackage);
15318                     }
15319                     dumper.dumpWithClient();
15320                 } else {
15321                     synchronized (this) {
15322                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15323                                 dumpPackage).dumpLocked();
15324                     }
15325                 }
15326             } else if ("locks".equals(cmd)) {
15327                 LockGuard.dump(fd, pw, args);
15328             } else {
15329                 // Dumping a single activity?
15330                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15331                         dumpFocusedStackOnly)) {
15332                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15333                     int res = shell.exec(this, null, fd, null, args, null,
15334                             new ResultReceiver(null));
15335                     if (res < 0) {
15336                         pw.println("Bad activity command, or no activities match: " + cmd);
15337                         pw.println("Use -h for help.");
15338                     }
15339                 }
15340             }
15341             if (!more) {
15342                 Binder.restoreCallingIdentity(origId);
15343                 return;
15344             }
15345         }
15346
15347         // No piece of data specified, dump everything.
15348         if (dumpCheckinFormat) {
15349             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15350         } else if (dumpClient) {
15351             ActiveServices.ServiceDumper sdumper;
15352             synchronized (this) {
15353                 mConstants.dump(pw);
15354                 pw.println();
15355                 if (dumpAll) {
15356                     pw.println("-------------------------------------------------------------------------------");
15357                 }
15358                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15359                 pw.println();
15360                 if (dumpAll) {
15361                     pw.println("-------------------------------------------------------------------------------");
15362                 }
15363                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15364                 pw.println();
15365                 if (dumpAll) {
15366                     pw.println("-------------------------------------------------------------------------------");
15367                 }
15368                 if (dumpAll || dumpPackage != null) {
15369                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15370                     pw.println();
15371                     if (dumpAll) {
15372                         pw.println("-------------------------------------------------------------------------------");
15373                     }
15374                 }
15375                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15376                 pw.println();
15377                 if (dumpAll) {
15378                     pw.println("-------------------------------------------------------------------------------");
15379                 }
15380                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15381                 pw.println();
15382                 if (dumpAll) {
15383                     pw.println("-------------------------------------------------------------------------------");
15384                 }
15385                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15386                         dumpPackage);
15387             }
15388             sdumper.dumpWithClient();
15389             pw.println();
15390             synchronized (this) {
15391                 if (dumpAll) {
15392                     pw.println("-------------------------------------------------------------------------------");
15393                 }
15394                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15395                 pw.println();
15396                 if (dumpAll) {
15397                     pw.println("-------------------------------------------------------------------------------");
15398                 }
15399                 dumpLastANRLocked(pw);
15400                 pw.println();
15401                 if (dumpAll) {
15402                     pw.println("-------------------------------------------------------------------------------");
15403                 }
15404                 dumpActivityStarterLocked(pw, dumpPackage);
15405                 pw.println();
15406                 if (dumpAll) {
15407                     pw.println("-------------------------------------------------------------------------------");
15408                 }
15409                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15410                 if (mAssociations.size() > 0) {
15411                     pw.println();
15412                     if (dumpAll) {
15413                         pw.println("-------------------------------------------------------------------------------");
15414                     }
15415                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15416                 }
15417                 pw.println();
15418                 if (dumpAll) {
15419                     pw.println("-------------------------------------------------------------------------------");
15420                 }
15421                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15422             }
15423
15424         } else {
15425             synchronized (this) {
15426                 mConstants.dump(pw);
15427                 pw.println();
15428                 if (dumpAll) {
15429                     pw.println("-------------------------------------------------------------------------------");
15430                 }
15431                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15432                 pw.println();
15433                 if (dumpAll) {
15434                     pw.println("-------------------------------------------------------------------------------");
15435                 }
15436                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15437                 pw.println();
15438                 if (dumpAll) {
15439                     pw.println("-------------------------------------------------------------------------------");
15440                 }
15441                 if (dumpAll || dumpPackage != null) {
15442                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15443                     pw.println();
15444                     if (dumpAll) {
15445                         pw.println("-------------------------------------------------------------------------------");
15446                     }
15447                 }
15448                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15449                 pw.println();
15450                 if (dumpAll) {
15451                     pw.println("-------------------------------------------------------------------------------");
15452                 }
15453                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15454                 pw.println();
15455                 if (dumpAll) {
15456                     pw.println("-------------------------------------------------------------------------------");
15457                 }
15458                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15459                         .dumpLocked();
15460                 pw.println();
15461                 if (dumpAll) {
15462                     pw.println("-------------------------------------------------------------------------------");
15463                 }
15464                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15465                 pw.println();
15466                 if (dumpAll) {
15467                     pw.println("-------------------------------------------------------------------------------");
15468                 }
15469                 dumpLastANRLocked(pw);
15470                 pw.println();
15471                 if (dumpAll) {
15472                     pw.println("-------------------------------------------------------------------------------");
15473                 }
15474                 dumpActivityStarterLocked(pw, dumpPackage);
15475                 pw.println();
15476                 if (dumpAll) {
15477                     pw.println("-------------------------------------------------------------------------------");
15478                 }
15479                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15480                 if (mAssociations.size() > 0) {
15481                     pw.println();
15482                     if (dumpAll) {
15483                         pw.println("-------------------------------------------------------------------------------");
15484                     }
15485                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15486                 }
15487                 pw.println();
15488                 if (dumpAll) {
15489                     pw.println("-------------------------------------------------------------------------------");
15490                 }
15491                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15492             }
15493         }
15494         Binder.restoreCallingIdentity(origId);
15495     }
15496
15497     private void dumpLastANRLocked(PrintWriter pw) {
15498         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15499         if (mLastANRState == null) {
15500             pw.println("  <no ANR has occurred since boot>");
15501         } else {
15502             pw.println(mLastANRState);
15503         }
15504     }
15505
15506     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15507         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15508         mActivityStarter.dump(pw, "", dumpPackage);
15509     }
15510
15511     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15512             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15513         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15514                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15515     }
15516
15517     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15518             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15519         pw.println(header);
15520
15521         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15522                 dumpPackage);
15523         boolean needSep = printedAnything;
15524
15525         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15526                 mStackSupervisor.getResumedActivityLocked(),
15527                 dumpPackage, needSep, "  ResumedActivity: ");
15528         if (printed) {
15529             printedAnything = true;
15530             needSep = false;
15531         }
15532
15533         if (dumpPackage == null) {
15534             if (needSep) {
15535                 pw.println();
15536             }
15537             printedAnything = true;
15538             mStackSupervisor.dump(pw, "  ");
15539         }
15540
15541         if (!printedAnything) {
15542             pw.println("  (nothing)");
15543         }
15544     }
15545
15546     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15547             int opti, boolean dumpAll, String dumpPackage) {
15548         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15549
15550         boolean printedAnything = false;
15551
15552         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15553             boolean printedHeader = false;
15554
15555             final int N = mRecentTasks.size();
15556             for (int i=0; i<N; i++) {
15557                 TaskRecord tr = mRecentTasks.get(i);
15558                 if (dumpPackage != null) {
15559                     if (tr.realActivity == null ||
15560                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15561                         continue;
15562                     }
15563                 }
15564                 if (!printedHeader) {
15565                     pw.println("  Recent tasks:");
15566                     printedHeader = true;
15567                     printedAnything = true;
15568                 }
15569                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15570                         pw.println(tr);
15571                 if (dumpAll) {
15572                     mRecentTasks.get(i).dump(pw, "    ");
15573                 }
15574             }
15575         }
15576
15577         if (!printedAnything) {
15578             pw.println("  (nothing)");
15579         }
15580     }
15581
15582     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15583             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15584         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15585
15586         int dumpUid = 0;
15587         if (dumpPackage != null) {
15588             IPackageManager pm = AppGlobals.getPackageManager();
15589             try {
15590                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15591             } catch (RemoteException e) {
15592             }
15593         }
15594
15595         boolean printedAnything = false;
15596
15597         final long now = SystemClock.uptimeMillis();
15598
15599         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15600             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15601                     = mAssociations.valueAt(i1);
15602             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15603                 SparseArray<ArrayMap<String, Association>> sourceUids
15604                         = targetComponents.valueAt(i2);
15605                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15606                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15607                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15608                         Association ass = sourceProcesses.valueAt(i4);
15609                         if (dumpPackage != null) {
15610                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15611                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15612                                 continue;
15613                             }
15614                         }
15615                         printedAnything = true;
15616                         pw.print("  ");
15617                         pw.print(ass.mTargetProcess);
15618                         pw.print("/");
15619                         UserHandle.formatUid(pw, ass.mTargetUid);
15620                         pw.print(" <- ");
15621                         pw.print(ass.mSourceProcess);
15622                         pw.print("/");
15623                         UserHandle.formatUid(pw, ass.mSourceUid);
15624                         pw.println();
15625                         pw.print("    via ");
15626                         pw.print(ass.mTargetComponent.flattenToShortString());
15627                         pw.println();
15628                         pw.print("    ");
15629                         long dur = ass.mTime;
15630                         if (ass.mNesting > 0) {
15631                             dur += now - ass.mStartTime;
15632                         }
15633                         TimeUtils.formatDuration(dur, pw);
15634                         pw.print(" (");
15635                         pw.print(ass.mCount);
15636                         pw.print(" times)");
15637                         pw.print("  ");
15638                         for (int i=0; i<ass.mStateTimes.length; i++) {
15639                             long amt = ass.mStateTimes[i];
15640                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15641                                 amt += now - ass.mLastStateUptime;
15642                             }
15643                             if (amt != 0) {
15644                                 pw.print(" ");
15645                                 pw.print(ProcessList.makeProcStateString(
15646                                             i + ActivityManager.MIN_PROCESS_STATE));
15647                                 pw.print("=");
15648                                 TimeUtils.formatDuration(amt, pw);
15649                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15650                                     pw.print("*");
15651                                 }
15652                             }
15653                         }
15654                         pw.println();
15655                         if (ass.mNesting > 0) {
15656                             pw.print("    Currently active: ");
15657                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15658                             pw.println();
15659                         }
15660                     }
15661                 }
15662             }
15663
15664         }
15665
15666         if (!printedAnything) {
15667             pw.println("  (nothing)");
15668         }
15669     }
15670
15671     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15672             String header, boolean needSep) {
15673         boolean printed = false;
15674         int whichAppId = -1;
15675         if (dumpPackage != null) {
15676             try {
15677                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15678                         dumpPackage, 0);
15679                 whichAppId = UserHandle.getAppId(info.uid);
15680             } catch (NameNotFoundException e) {
15681                 e.printStackTrace();
15682             }
15683         }
15684         for (int i=0; i<uids.size(); i++) {
15685             UidRecord uidRec = uids.valueAt(i);
15686             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15687                 continue;
15688             }
15689             if (!printed) {
15690                 printed = true;
15691                 if (needSep) {
15692                     pw.println();
15693                 }
15694                 pw.print("  ");
15695                 pw.println(header);
15696                 needSep = true;
15697             }
15698             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15699             pw.print(": "); pw.println(uidRec);
15700         }
15701         return printed;
15702     }
15703
15704     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15705             int opti, boolean dumpAll, String dumpPackage) {
15706         boolean needSep = false;
15707         boolean printedAnything = false;
15708         int numPers = 0;
15709
15710         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15711
15712         if (dumpAll) {
15713             final int NP = mProcessNames.getMap().size();
15714             for (int ip=0; ip<NP; ip++) {
15715                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15716                 final int NA = procs.size();
15717                 for (int ia=0; ia<NA; ia++) {
15718                     ProcessRecord r = procs.valueAt(ia);
15719                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15720                         continue;
15721                     }
15722                     if (!needSep) {
15723                         pw.println("  All known processes:");
15724                         needSep = true;
15725                         printedAnything = true;
15726                     }
15727                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15728                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15729                         pw.print(" "); pw.println(r);
15730                     r.dump(pw, "    ");
15731                     if (r.persistent) {
15732                         numPers++;
15733                     }
15734                 }
15735             }
15736         }
15737
15738         if (mIsolatedProcesses.size() > 0) {
15739             boolean printed = false;
15740             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15741                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15742                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15743                     continue;
15744                 }
15745                 if (!printed) {
15746                     if (needSep) {
15747                         pw.println();
15748                     }
15749                     pw.println("  Isolated process list (sorted by uid):");
15750                     printedAnything = true;
15751                     printed = true;
15752                     needSep = true;
15753                 }
15754                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15755                 pw.println(r);
15756             }
15757         }
15758
15759         if (mActiveInstrumentation.size() > 0) {
15760             boolean printed = false;
15761             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15762                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15763                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15764                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15765                     continue;
15766                 }
15767                 if (!printed) {
15768                     if (needSep) {
15769                         pw.println();
15770                     }
15771                     pw.println("  Active instrumentation:");
15772                     printedAnything = true;
15773                     printed = true;
15774                     needSep = true;
15775                 }
15776                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15777                 pw.println(ai);
15778                 ai.dump(pw, "      ");
15779             }
15780         }
15781
15782         if (mActiveUids.size() > 0) {
15783             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15784                 printedAnything = needSep = true;
15785             }
15786         }
15787         if (dumpAll) {
15788             if (mValidateUids.size() > 0) {
15789                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15790                     printedAnything = needSep = true;
15791                 }
15792             }
15793         }
15794
15795         if (mLruProcesses.size() > 0) {
15796             if (needSep) {
15797                 pw.println();
15798             }
15799             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15800                     pw.print(" total, non-act at ");
15801                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15802                     pw.print(", non-svc at ");
15803                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15804                     pw.println("):");
15805             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15806             needSep = true;
15807             printedAnything = true;
15808         }
15809
15810         if (dumpAll || dumpPackage != null) {
15811             synchronized (mPidsSelfLocked) {
15812                 boolean printed = false;
15813                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15814                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15815                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15816                         continue;
15817                     }
15818                     if (!printed) {
15819                         if (needSep) pw.println();
15820                         needSep = true;
15821                         pw.println("  PID mappings:");
15822                         printed = true;
15823                         printedAnything = true;
15824                     }
15825                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15826                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15827                 }
15828             }
15829         }
15830
15831         if (mImportantProcesses.size() > 0) {
15832             synchronized (mPidsSelfLocked) {
15833                 boolean printed = false;
15834                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15835                     ProcessRecord r = mPidsSelfLocked.get(
15836                             mImportantProcesses.valueAt(i).pid);
15837                     if (dumpPackage != null && (r == null
15838                             || !r.pkgList.containsKey(dumpPackage))) {
15839                         continue;
15840                     }
15841                     if (!printed) {
15842                         if (needSep) pw.println();
15843                         needSep = true;
15844                         pw.println("  Foreground Processes:");
15845                         printed = true;
15846                         printedAnything = true;
15847                     }
15848                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15849                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15850                 }
15851             }
15852         }
15853
15854         if (mPersistentStartingProcesses.size() > 0) {
15855             if (needSep) pw.println();
15856             needSep = true;
15857             printedAnything = true;
15858             pw.println("  Persisent processes that are starting:");
15859             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15860                     "Starting Norm", "Restarting PERS", dumpPackage);
15861         }
15862
15863         if (mRemovedProcesses.size() > 0) {
15864             if (needSep) pw.println();
15865             needSep = true;
15866             printedAnything = true;
15867             pw.println("  Processes that are being removed:");
15868             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15869                     "Removed Norm", "Removed PERS", dumpPackage);
15870         }
15871
15872         if (mProcessesOnHold.size() > 0) {
15873             if (needSep) pw.println();
15874             needSep = true;
15875             printedAnything = true;
15876             pw.println("  Processes that are on old until the system is ready:");
15877             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15878                     "OnHold Norm", "OnHold PERS", dumpPackage);
15879         }
15880
15881         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15882
15883         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15884         if (needSep) {
15885             printedAnything = true;
15886         }
15887
15888         if (dumpPackage == null) {
15889             pw.println();
15890             needSep = false;
15891             mUserController.dump(pw, dumpAll);
15892         }
15893         if (mHomeProcess != null && (dumpPackage == null
15894                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15895             if (needSep) {
15896                 pw.println();
15897                 needSep = false;
15898             }
15899             pw.println("  mHomeProcess: " + mHomeProcess);
15900         }
15901         if (mPreviousProcess != null && (dumpPackage == null
15902                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15903             if (needSep) {
15904                 pw.println();
15905                 needSep = false;
15906             }
15907             pw.println("  mPreviousProcess: " + mPreviousProcess);
15908         }
15909         if (dumpAll) {
15910             StringBuilder sb = new StringBuilder(128);
15911             sb.append("  mPreviousProcessVisibleTime: ");
15912             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15913             pw.println(sb);
15914         }
15915         if (mHeavyWeightProcess != null && (dumpPackage == null
15916                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15917             if (needSep) {
15918                 pw.println();
15919                 needSep = false;
15920             }
15921             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15922         }
15923         if (dumpPackage == null) {
15924             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15925             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15926         }
15927         if (dumpAll) {
15928             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15929             if (mCompatModePackages.getPackages().size() > 0) {
15930                 boolean printed = false;
15931                 for (Map.Entry<String, Integer> entry
15932                         : mCompatModePackages.getPackages().entrySet()) {
15933                     String pkg = entry.getKey();
15934                     int mode = entry.getValue();
15935                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15936                         continue;
15937                     }
15938                     if (!printed) {
15939                         pw.println("  mScreenCompatPackages:");
15940                         printed = true;
15941                     }
15942                     pw.print("    "); pw.print(pkg); pw.print(": ");
15943                             pw.print(mode); pw.println();
15944                 }
15945             }
15946             final int NI = mUidObservers.getRegisteredCallbackCount();
15947             boolean printed = false;
15948             for (int i=0; i<NI; i++) {
15949                 final UidObserverRegistration reg = (UidObserverRegistration)
15950                         mUidObservers.getRegisteredCallbackCookie(i);
15951                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15952                     if (!printed) {
15953                         pw.println("  mUidObservers:");
15954                         printed = true;
15955                     }
15956                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15957                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15958                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15959                         pw.print(" IDLE");
15960                     }
15961                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15962                         pw.print(" ACT" );
15963                     }
15964                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15965                         pw.print(" GONE");
15966                     }
15967                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15968                         pw.print(" STATE");
15969                         pw.print(" (cut="); pw.print(reg.cutpoint);
15970                         pw.print(")");
15971                     }
15972                     pw.println();
15973                     if (reg.lastProcStates != null) {
15974                         final int NJ = reg.lastProcStates.size();
15975                         for (int j=0; j<NJ; j++) {
15976                             pw.print("      Last ");
15977                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15978                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15979                         }
15980                     }
15981                 }
15982             }
15983             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15984             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15985             if (mPendingTempWhitelist.size() > 0) {
15986                 pw.println("  mPendingTempWhitelist:");
15987                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15988                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15989                     pw.print("    ");
15990                     UserHandle.formatUid(pw, ptw.targetUid);
15991                     pw.print(": ");
15992                     TimeUtils.formatDuration(ptw.duration, pw);
15993                     pw.print(" ");
15994                     pw.println(ptw.tag);
15995                 }
15996             }
15997         }
15998         if (dumpPackage == null) {
15999             pw.println("  mWakefulness="
16000                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
16001             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
16002             pw.println("  mSleeping=" + mSleeping);
16003             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
16004             if (mRunningVoice != null) {
16005                 pw.println("  mRunningVoice=" + mRunningVoice);
16006                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
16007             }
16008         }
16009         pw.println("  mVrController=" + mVrController);
16010         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
16011                 || mOrigWaitForDebugger) {
16012             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
16013                     || dumpPackage.equals(mOrigDebugApp)) {
16014                 if (needSep) {
16015                     pw.println();
16016                     needSep = false;
16017                 }
16018                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
16019                         + " mDebugTransient=" + mDebugTransient
16020                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
16021             }
16022         }
16023         if (mCurAppTimeTracker != null) {
16024             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
16025         }
16026         if (mMemWatchProcesses.getMap().size() > 0) {
16027             pw.println("  Mem watch processes:");
16028             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
16029                     = mMemWatchProcesses.getMap();
16030             for (int i=0; i<procs.size(); i++) {
16031                 final String proc = procs.keyAt(i);
16032                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
16033                 for (int j=0; j<uids.size(); j++) {
16034                     if (needSep) {
16035                         pw.println();
16036                         needSep = false;
16037                     }
16038                     StringBuilder sb = new StringBuilder();
16039                     sb.append("    ").append(proc).append('/');
16040                     UserHandle.formatUid(sb, uids.keyAt(j));
16041                     Pair<Long, String> val = uids.valueAt(j);
16042                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
16043                     if (val.second != null) {
16044                         sb.append(", report to ").append(val.second);
16045                     }
16046                     pw.println(sb.toString());
16047                 }
16048             }
16049             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
16050             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
16051             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
16052                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
16053         }
16054         if (mTrackAllocationApp != null) {
16055             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
16056                 if (needSep) {
16057                     pw.println();
16058                     needSep = false;
16059                 }
16060                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16061             }
16062         }
16063         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16064                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16065             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16066                 if (needSep) {
16067                     pw.println();
16068                     needSep = false;
16069                 }
16070                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16071                 if (mProfilerInfo != null) {
16072                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16073                             mProfilerInfo.profileFd);
16074                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16075                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16076                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16077                     pw.println("  mProfileType=" + mProfileType);
16078                 }
16079             }
16080         }
16081         if (mNativeDebuggingApp != null) {
16082             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16083                 if (needSep) {
16084                     pw.println();
16085                     needSep = false;
16086                 }
16087                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16088             }
16089         }
16090         if (dumpPackage == null) {
16091             if (mAlwaysFinishActivities) {
16092                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16093             }
16094             if (mController != null) {
16095                 pw.println("  mController=" + mController
16096                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16097             }
16098             if (dumpAll) {
16099                 pw.println("  Total persistent processes: " + numPers);
16100                 pw.println("  mProcessesReady=" + mProcessesReady
16101                         + " mSystemReady=" + mSystemReady
16102                         + " mBooted=" + mBooted
16103                         + " mFactoryTest=" + mFactoryTest);
16104                 pw.println("  mBooting=" + mBooting
16105                         + " mCallFinishBooting=" + mCallFinishBooting
16106                         + " mBootAnimationComplete=" + mBootAnimationComplete);
16107                 pw.print("  mLastPowerCheckUptime=");
16108                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16109                         pw.println("");
16110                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16111                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16112                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16113                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16114                         + " (" + mLruProcesses.size() + " total)"
16115                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16116                         + " mNumServiceProcs=" + mNumServiceProcs
16117                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16118                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16119                         + " mLastMemoryLevel=" + mLastMemoryLevel
16120                         + " mLastNumProcesses=" + mLastNumProcesses);
16121                 long now = SystemClock.uptimeMillis();
16122                 pw.print("  mLastIdleTime=");
16123                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
16124                         pw.print(" mLowRamSinceLastIdle=");
16125                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16126                         pw.println();
16127             }
16128         }
16129
16130         if (!printedAnything) {
16131             pw.println("  (nothing)");
16132         }
16133     }
16134
16135     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16136             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16137         if (mProcessesToGc.size() > 0) {
16138             boolean printed = false;
16139             long now = SystemClock.uptimeMillis();
16140             for (int i=0; i<mProcessesToGc.size(); i++) {
16141                 ProcessRecord proc = mProcessesToGc.get(i);
16142                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16143                     continue;
16144                 }
16145                 if (!printed) {
16146                     if (needSep) pw.println();
16147                     needSep = true;
16148                     pw.println("  Processes that are waiting to GC:");
16149                     printed = true;
16150                 }
16151                 pw.print("    Process "); pw.println(proc);
16152                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16153                         pw.print(", last gced=");
16154                         pw.print(now-proc.lastRequestedGc);
16155                         pw.print(" ms ago, last lowMem=");
16156                         pw.print(now-proc.lastLowMemory);
16157                         pw.println(" ms ago");
16158
16159             }
16160         }
16161         return needSep;
16162     }
16163
16164     void printOomLevel(PrintWriter pw, String name, int adj) {
16165         pw.print("    ");
16166         if (adj >= 0) {
16167             pw.print(' ');
16168             if (adj < 10) pw.print(' ');
16169         } else {
16170             if (adj > -10) pw.print(' ');
16171         }
16172         pw.print(adj);
16173         pw.print(": ");
16174         pw.print(name);
16175         pw.print(" (");
16176         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16177         pw.println(")");
16178     }
16179
16180     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16181             int opti, boolean dumpAll) {
16182         boolean needSep = false;
16183
16184         if (mLruProcesses.size() > 0) {
16185             if (needSep) pw.println();
16186             needSep = true;
16187             pw.println("  OOM levels:");
16188             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16189             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16190             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16191             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16192             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16193             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16194             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16195             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16196             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16197             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16198             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16199             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16200             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16201             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16202
16203             if (needSep) pw.println();
16204             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16205                     pw.print(" total, non-act at ");
16206                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16207                     pw.print(", non-svc at ");
16208                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16209                     pw.println("):");
16210             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16211             needSep = true;
16212         }
16213
16214         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16215
16216         pw.println();
16217         pw.println("  mHomeProcess: " + mHomeProcess);
16218         pw.println("  mPreviousProcess: " + mPreviousProcess);
16219         if (mHeavyWeightProcess != null) {
16220             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16221         }
16222
16223         return true;
16224     }
16225
16226     /**
16227      * There are three ways to call this:
16228      *  - no provider specified: dump all the providers
16229      *  - a flattened component name that matched an existing provider was specified as the
16230      *    first arg: dump that one provider
16231      *  - the first arg isn't the flattened component name of an existing provider:
16232      *    dump all providers whose component contains the first arg as a substring
16233      */
16234     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16235             int opti, boolean dumpAll) {
16236         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16237     }
16238
16239     static class ItemMatcher {
16240         ArrayList<ComponentName> components;
16241         ArrayList<String> strings;
16242         ArrayList<Integer> objects;
16243         boolean all;
16244
16245         ItemMatcher() {
16246             all = true;
16247         }
16248
16249         void build(String name) {
16250             ComponentName componentName = ComponentName.unflattenFromString(name);
16251             if (componentName != null) {
16252                 if (components == null) {
16253                     components = new ArrayList<ComponentName>();
16254                 }
16255                 components.add(componentName);
16256                 all = false;
16257             } else {
16258                 int objectId = 0;
16259                 // Not a '/' separated full component name; maybe an object ID?
16260                 try {
16261                     objectId = Integer.parseInt(name, 16);
16262                     if (objects == null) {
16263                         objects = new ArrayList<Integer>();
16264                     }
16265                     objects.add(objectId);
16266                     all = false;
16267                 } catch (RuntimeException e) {
16268                     // Not an integer; just do string match.
16269                     if (strings == null) {
16270                         strings = new ArrayList<String>();
16271                     }
16272                     strings.add(name);
16273                     all = false;
16274                 }
16275             }
16276         }
16277
16278         int build(String[] args, int opti) {
16279             for (; opti<args.length; opti++) {
16280                 String name = args[opti];
16281                 if ("--".equals(name)) {
16282                     return opti+1;
16283                 }
16284                 build(name);
16285             }
16286             return opti;
16287         }
16288
16289         boolean match(Object object, ComponentName comp) {
16290             if (all) {
16291                 return true;
16292             }
16293             if (components != null) {
16294                 for (int i=0; i<components.size(); i++) {
16295                     if (components.get(i).equals(comp)) {
16296                         return true;
16297                     }
16298                 }
16299             }
16300             if (objects != null) {
16301                 for (int i=0; i<objects.size(); i++) {
16302                     if (System.identityHashCode(object) == objects.get(i)) {
16303                         return true;
16304                     }
16305                 }
16306             }
16307             if (strings != null) {
16308                 String flat = comp.flattenToString();
16309                 for (int i=0; i<strings.size(); i++) {
16310                     if (flat.contains(strings.get(i))) {
16311                         return true;
16312                     }
16313                 }
16314             }
16315             return false;
16316         }
16317     }
16318
16319     /**
16320      * There are three things that cmd can be:
16321      *  - a flattened component name that matches an existing activity
16322      *  - the cmd arg isn't the flattened component name of an existing activity:
16323      *    dump all activity whose component contains the cmd as a substring
16324      *  - A hex number of the ActivityRecord object instance.
16325      *
16326      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16327      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16328      */
16329     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16330             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16331         ArrayList<ActivityRecord> activities;
16332
16333         synchronized (this) {
16334             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16335                     dumpFocusedStackOnly);
16336         }
16337
16338         if (activities.size() <= 0) {
16339             return false;
16340         }
16341
16342         String[] newArgs = new String[args.length - opti];
16343         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16344
16345         TaskRecord lastTask = null;
16346         boolean needSep = false;
16347         for (int i=activities.size()-1; i>=0; i--) {
16348             ActivityRecord r = activities.get(i);
16349             if (needSep) {
16350                 pw.println();
16351             }
16352             needSep = true;
16353             synchronized (this) {
16354                 final TaskRecord task = r.getTask();
16355                 if (lastTask != task) {
16356                     lastTask = task;
16357                     pw.print("TASK "); pw.print(lastTask.affinity);
16358                             pw.print(" id="); pw.print(lastTask.taskId);
16359                             pw.print(" userId="); pw.println(lastTask.userId);
16360                     if (dumpAll) {
16361                         lastTask.dump(pw, "  ");
16362                     }
16363                 }
16364             }
16365             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16366         }
16367         return true;
16368     }
16369
16370     /**
16371      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16372      * there is a thread associated with the activity.
16373      */
16374     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16375             final ActivityRecord r, String[] args, boolean dumpAll) {
16376         String innerPrefix = prefix + "  ";
16377         synchronized (this) {
16378             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16379                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16380                     pw.print(" pid=");
16381                     if (r.app != null) pw.println(r.app.pid);
16382                     else pw.println("(not running)");
16383             if (dumpAll) {
16384                 r.dump(pw, innerPrefix);
16385             }
16386         }
16387         if (r.app != null && r.app.thread != null) {
16388             // flush anything that is already in the PrintWriter since the thread is going
16389             // to write to the file descriptor directly
16390             pw.flush();
16391             try {
16392                 TransferPipe tp = new TransferPipe();
16393                 try {
16394                     r.app.thread.dumpActivity(tp.getWriteFd(),
16395                             r.appToken, innerPrefix, args);
16396                     tp.go(fd);
16397                 } finally {
16398                     tp.kill();
16399                 }
16400             } catch (IOException e) {
16401                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16402             } catch (RemoteException e) {
16403                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16404             }
16405         }
16406     }
16407
16408     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16409             int opti, boolean dumpAll, String dumpPackage) {
16410         boolean needSep = false;
16411         boolean onlyHistory = false;
16412         boolean printedAnything = false;
16413
16414         if ("history".equals(dumpPackage)) {
16415             if (opti < args.length && "-s".equals(args[opti])) {
16416                 dumpAll = false;
16417             }
16418             onlyHistory = true;
16419             dumpPackage = null;
16420         }
16421
16422         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16423         if (!onlyHistory && dumpAll) {
16424             if (mRegisteredReceivers.size() > 0) {
16425                 boolean printed = false;
16426                 Iterator it = mRegisteredReceivers.values().iterator();
16427                 while (it.hasNext()) {
16428                     ReceiverList r = (ReceiverList)it.next();
16429                     if (dumpPackage != null && (r.app == null ||
16430                             !dumpPackage.equals(r.app.info.packageName))) {
16431                         continue;
16432                     }
16433                     if (!printed) {
16434                         pw.println("  Registered Receivers:");
16435                         needSep = true;
16436                         printed = true;
16437                         printedAnything = true;
16438                     }
16439                     pw.print("  * "); pw.println(r);
16440                     r.dump(pw, "    ");
16441                 }
16442             }
16443
16444             if (mReceiverResolver.dump(pw, needSep ?
16445                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16446                     "    ", dumpPackage, false, false)) {
16447                 needSep = true;
16448                 printedAnything = true;
16449             }
16450         }
16451
16452         for (BroadcastQueue q : mBroadcastQueues) {
16453             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16454             printedAnything |= needSep;
16455         }
16456
16457         needSep = true;
16458
16459         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16460             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16461                 if (needSep) {
16462                     pw.println();
16463                 }
16464                 needSep = true;
16465                 printedAnything = true;
16466                 pw.print("  Sticky broadcasts for user ");
16467                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16468                 StringBuilder sb = new StringBuilder(128);
16469                 for (Map.Entry<String, ArrayList<Intent>> ent
16470                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16471                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16472                     if (dumpAll) {
16473                         pw.println(":");
16474                         ArrayList<Intent> intents = ent.getValue();
16475                         final int N = intents.size();
16476                         for (int i=0; i<N; i++) {
16477                             sb.setLength(0);
16478                             sb.append("    Intent: ");
16479                             intents.get(i).toShortString(sb, false, true, false, false);
16480                             pw.println(sb.toString());
16481                             Bundle bundle = intents.get(i).getExtras();
16482                             if (bundle != null) {
16483                                 pw.print("      ");
16484                                 pw.println(bundle.toString());
16485                             }
16486                         }
16487                     } else {
16488                         pw.println("");
16489                     }
16490                 }
16491             }
16492         }
16493
16494         if (!onlyHistory && dumpAll) {
16495             pw.println();
16496             for (BroadcastQueue queue : mBroadcastQueues) {
16497                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16498                         + queue.mBroadcastsScheduled);
16499             }
16500             pw.println("  mHandler:");
16501             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16502             needSep = true;
16503             printedAnything = true;
16504         }
16505
16506         if (!printedAnything) {
16507             pw.println("  (nothing)");
16508         }
16509     }
16510
16511     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16512             int opti, boolean dumpAll, String dumpPackage) {
16513         if (mCurBroadcastStats == null) {
16514             return;
16515         }
16516
16517         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16518         final long now = SystemClock.elapsedRealtime();
16519         if (mLastBroadcastStats != null) {
16520             pw.print("  Last stats (from ");
16521             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16522             pw.print(" to ");
16523             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16524             pw.print(", ");
16525             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16526                     - mLastBroadcastStats.mStartUptime, pw);
16527             pw.println(" uptime):");
16528             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16529                 pw.println("    (nothing)");
16530             }
16531             pw.println();
16532         }
16533         pw.print("  Current stats (from ");
16534         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16535         pw.print(" to now, ");
16536         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16537                 - mCurBroadcastStats.mStartUptime, pw);
16538         pw.println(" uptime):");
16539         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16540             pw.println("    (nothing)");
16541         }
16542     }
16543
16544     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16545             int opti, boolean fullCheckin, String dumpPackage) {
16546         if (mCurBroadcastStats == null) {
16547             return;
16548         }
16549
16550         if (mLastBroadcastStats != null) {
16551             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16552             if (fullCheckin) {
16553                 mLastBroadcastStats = null;
16554                 return;
16555             }
16556         }
16557         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16558         if (fullCheckin) {
16559             mCurBroadcastStats = null;
16560         }
16561     }
16562
16563     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16564             int opti, boolean dumpAll, String dumpPackage) {
16565         boolean needSep;
16566         boolean printedAnything = false;
16567
16568         ItemMatcher matcher = new ItemMatcher();
16569         matcher.build(args, opti);
16570
16571         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16572
16573         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16574         printedAnything |= needSep;
16575
16576         if (mLaunchingProviders.size() > 0) {
16577             boolean printed = false;
16578             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16579                 ContentProviderRecord r = mLaunchingProviders.get(i);
16580                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16581                     continue;
16582                 }
16583                 if (!printed) {
16584                     if (needSep) pw.println();
16585                     needSep = true;
16586                     pw.println("  Launching content providers:");
16587                     printed = true;
16588                     printedAnything = true;
16589                 }
16590                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16591                         pw.println(r);
16592             }
16593         }
16594
16595         if (!printedAnything) {
16596             pw.println("  (nothing)");
16597         }
16598     }
16599
16600     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16601             int opti, boolean dumpAll, String dumpPackage) {
16602         boolean needSep = false;
16603         boolean printedAnything = false;
16604
16605         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16606
16607         if (mGrantedUriPermissions.size() > 0) {
16608             boolean printed = false;
16609             int dumpUid = -2;
16610             if (dumpPackage != null) {
16611                 try {
16612                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16613                             MATCH_ANY_USER, 0);
16614                 } catch (NameNotFoundException e) {
16615                     dumpUid = -1;
16616                 }
16617             }
16618             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16619                 int uid = mGrantedUriPermissions.keyAt(i);
16620                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16621                     continue;
16622                 }
16623                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16624                 if (!printed) {
16625                     if (needSep) pw.println();
16626                     needSep = true;
16627                     pw.println("  Granted Uri Permissions:");
16628                     printed = true;
16629                     printedAnything = true;
16630                 }
16631                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16632                 for (UriPermission perm : perms.values()) {
16633                     pw.print("    "); pw.println(perm);
16634                     if (dumpAll) {
16635                         perm.dump(pw, "      ");
16636                     }
16637                 }
16638             }
16639         }
16640
16641         if (!printedAnything) {
16642             pw.println("  (nothing)");
16643         }
16644     }
16645
16646     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16647             int opti, boolean dumpAll, String dumpPackage) {
16648         boolean printed = false;
16649
16650         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16651
16652         if (mIntentSenderRecords.size() > 0) {
16653             // Organize these by package name, so they are easier to read.
16654             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16655             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16656             final Iterator<WeakReference<PendingIntentRecord>> it
16657                     = mIntentSenderRecords.values().iterator();
16658             while (it.hasNext()) {
16659                 WeakReference<PendingIntentRecord> ref = it.next();
16660                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16661                 if (rec == null) {
16662                     weakRefs.add(ref);
16663                     continue;
16664                 }
16665                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16666                     continue;
16667                 }
16668                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16669                 if (list == null) {
16670                     list = new ArrayList<>();
16671                     byPackage.put(rec.key.packageName, list);
16672                 }
16673                 list.add(rec);
16674             }
16675             for (int i = 0; i < byPackage.size(); i++) {
16676                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16677                 printed = true;
16678                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16679                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16680                 for (int j = 0; j < intents.size(); j++) {
16681                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16682                     if (dumpAll) {
16683                         intents.get(j).dump(pw, "      ");
16684                     }
16685                 }
16686             }
16687             if (weakRefs.size() > 0) {
16688                 printed = true;
16689                 pw.println("  * WEAK REFS:");
16690                 for (int i = 0; i < weakRefs.size(); i++) {
16691                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16692                 }
16693             }
16694         }
16695
16696         if (!printed) {
16697             pw.println("  (nothing)");
16698         }
16699     }
16700
16701     private static final int dumpProcessList(PrintWriter pw,
16702             ActivityManagerService service, List list,
16703             String prefix, String normalLabel, String persistentLabel,
16704             String dumpPackage) {
16705         int numPers = 0;
16706         final int N = list.size()-1;
16707         for (int i=N; i>=0; i--) {
16708             ProcessRecord r = (ProcessRecord)list.get(i);
16709             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16710                 continue;
16711             }
16712             pw.println(String.format("%s%s #%2d: %s",
16713                     prefix, (r.persistent ? persistentLabel : normalLabel),
16714                     i, r.toString()));
16715             if (r.persistent) {
16716                 numPers++;
16717             }
16718         }
16719         return numPers;
16720     }
16721
16722     private static final boolean dumpProcessOomList(PrintWriter pw,
16723             ActivityManagerService service, List<ProcessRecord> origList,
16724             String prefix, String normalLabel, String persistentLabel,
16725             boolean inclDetails, String dumpPackage) {
16726
16727         ArrayList<Pair<ProcessRecord, Integer>> list
16728                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16729         for (int i=0; i<origList.size(); i++) {
16730             ProcessRecord r = origList.get(i);
16731             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16732                 continue;
16733             }
16734             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16735         }
16736
16737         if (list.size() <= 0) {
16738             return false;
16739         }
16740
16741         Comparator<Pair<ProcessRecord, Integer>> comparator
16742                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16743             @Override
16744             public int compare(Pair<ProcessRecord, Integer> object1,
16745                     Pair<ProcessRecord, Integer> object2) {
16746                 if (object1.first.setAdj != object2.first.setAdj) {
16747                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16748                 }
16749                 if (object1.first.setProcState != object2.first.setProcState) {
16750                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16751                 }
16752                 if (object1.second.intValue() != object2.second.intValue()) {
16753                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16754                 }
16755                 return 0;
16756             }
16757         };
16758
16759         Collections.sort(list, comparator);
16760
16761         final long curUptime = SystemClock.uptimeMillis();
16762         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16763
16764         for (int i=list.size()-1; i>=0; i--) {
16765             ProcessRecord r = list.get(i).first;
16766             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16767             char schedGroup;
16768             switch (r.setSchedGroup) {
16769                 case ProcessList.SCHED_GROUP_BACKGROUND:
16770                     schedGroup = 'B';
16771                     break;
16772                 case ProcessList.SCHED_GROUP_DEFAULT:
16773                     schedGroup = 'F';
16774                     break;
16775                 case ProcessList.SCHED_GROUP_TOP_APP:
16776                     schedGroup = 'T';
16777                     break;
16778                 default:
16779                     schedGroup = '?';
16780                     break;
16781             }
16782             char foreground;
16783             if (r.foregroundActivities) {
16784                 foreground = 'A';
16785             } else if (r.foregroundServices) {
16786                 foreground = 'S';
16787             } else {
16788                 foreground = ' ';
16789             }
16790             String procState = ProcessList.makeProcStateString(r.curProcState);
16791             pw.print(prefix);
16792             pw.print(r.persistent ? persistentLabel : normalLabel);
16793             pw.print(" #");
16794             int num = (origList.size()-1)-list.get(i).second;
16795             if (num < 10) pw.print(' ');
16796             pw.print(num);
16797             pw.print(": ");
16798             pw.print(oomAdj);
16799             pw.print(' ');
16800             pw.print(schedGroup);
16801             pw.print('/');
16802             pw.print(foreground);
16803             pw.print('/');
16804             pw.print(procState);
16805             pw.print(" trm:");
16806             if (r.trimMemoryLevel < 10) pw.print(' ');
16807             pw.print(r.trimMemoryLevel);
16808             pw.print(' ');
16809             pw.print(r.toShortString());
16810             pw.print(" (");
16811             pw.print(r.adjType);
16812             pw.println(')');
16813             if (r.adjSource != null || r.adjTarget != null) {
16814                 pw.print(prefix);
16815                 pw.print("    ");
16816                 if (r.adjTarget instanceof ComponentName) {
16817                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16818                 } else if (r.adjTarget != null) {
16819                     pw.print(r.adjTarget.toString());
16820                 } else {
16821                     pw.print("{null}");
16822                 }
16823                 pw.print("<=");
16824                 if (r.adjSource instanceof ProcessRecord) {
16825                     pw.print("Proc{");
16826                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16827                     pw.println("}");
16828                 } else if (r.adjSource != null) {
16829                     pw.println(r.adjSource.toString());
16830                 } else {
16831                     pw.println("{null}");
16832                 }
16833             }
16834             if (inclDetails) {
16835                 pw.print(prefix);
16836                 pw.print("    ");
16837                 pw.print("oom: max="); pw.print(r.maxAdj);
16838                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16839                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16840                 pw.print(" cur="); pw.print(r.curAdj);
16841                 pw.print(" set="); pw.println(r.setAdj);
16842                 pw.print(prefix);
16843                 pw.print("    ");
16844                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16845                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16846                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16847                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16848                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16849                 pw.println();
16850                 pw.print(prefix);
16851                 pw.print("    ");
16852                 pw.print("cached="); pw.print(r.cached);
16853                 pw.print(" empty="); pw.print(r.empty);
16854                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16855
16856                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16857                     if (r.lastCpuTime != 0) {
16858                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16859                         pw.print(prefix);
16860                         pw.print("    ");
16861                         pw.print("run cpu over ");
16862                         TimeUtils.formatDuration(uptimeSince, pw);
16863                         pw.print(" used ");
16864                         TimeUtils.formatDuration(timeUsed, pw);
16865                         pw.print(" (");
16866                         pw.print((timeUsed*100)/uptimeSince);
16867                         pw.println("%)");
16868                     }
16869                 }
16870             }
16871         }
16872         return true;
16873     }
16874
16875     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16876             String[] args) {
16877         ArrayList<ProcessRecord> procs;
16878         synchronized (this) {
16879             if (args != null && args.length > start
16880                     && args[start].charAt(0) != '-') {
16881                 procs = new ArrayList<ProcessRecord>();
16882                 int pid = -1;
16883                 try {
16884                     pid = Integer.parseInt(args[start]);
16885                 } catch (NumberFormatException e) {
16886                 }
16887                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16888                     ProcessRecord proc = mLruProcesses.get(i);
16889                     if (proc.pid == pid) {
16890                         procs.add(proc);
16891                     } else if (allPkgs && proc.pkgList != null
16892                             && proc.pkgList.containsKey(args[start])) {
16893                         procs.add(proc);
16894                     } else if (proc.processName.equals(args[start])) {
16895                         procs.add(proc);
16896                     }
16897                 }
16898                 if (procs.size() <= 0) {
16899                     return null;
16900                 }
16901             } else {
16902                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16903             }
16904         }
16905         return procs;
16906     }
16907
16908     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16909             PrintWriter pw, String[] args) {
16910         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16911         if (procs == null) {
16912             pw.println("No process found for: " + args[0]);
16913             return;
16914         }
16915
16916         long uptime = SystemClock.uptimeMillis();
16917         long realtime = SystemClock.elapsedRealtime();
16918         pw.println("Applications Graphics Acceleration Info:");
16919         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16920
16921         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16922             ProcessRecord r = procs.get(i);
16923             if (r.thread != null) {
16924                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16925                 pw.flush();
16926                 try {
16927                     TransferPipe tp = new TransferPipe();
16928                     try {
16929                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16930                         tp.go(fd);
16931                     } finally {
16932                         tp.kill();
16933                     }
16934                 } catch (IOException e) {
16935                     pw.println("Failure while dumping the app: " + r);
16936                     pw.flush();
16937                 } catch (RemoteException e) {
16938                     pw.println("Got a RemoteException while dumping the app " + r);
16939                     pw.flush();
16940                 }
16941             }
16942         }
16943     }
16944
16945     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16946         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16947         if (procs == null) {
16948             pw.println("No process found for: " + args[0]);
16949             return;
16950         }
16951
16952         pw.println("Applications Database Info:");
16953
16954         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16955             ProcessRecord r = procs.get(i);
16956             if (r.thread != null) {
16957                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16958                 pw.flush();
16959                 try {
16960                     TransferPipe tp = new TransferPipe();
16961                     try {
16962                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16963                         tp.go(fd);
16964                     } finally {
16965                         tp.kill();
16966                     }
16967                 } catch (IOException e) {
16968                     pw.println("Failure while dumping the app: " + r);
16969                     pw.flush();
16970                 } catch (RemoteException e) {
16971                     pw.println("Got a RemoteException while dumping the app " + r);
16972                     pw.flush();
16973                 }
16974             }
16975         }
16976     }
16977
16978     final static class MemItem {
16979         final boolean isProc;
16980         final String label;
16981         final String shortLabel;
16982         final long pss;
16983         final long swapPss;
16984         final int id;
16985         final boolean hasActivities;
16986         ArrayList<MemItem> subitems;
16987
16988         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16989                 boolean _hasActivities) {
16990             isProc = true;
16991             label = _label;
16992             shortLabel = _shortLabel;
16993             pss = _pss;
16994             swapPss = _swapPss;
16995             id = _id;
16996             hasActivities = _hasActivities;
16997         }
16998
16999         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
17000             isProc = false;
17001             label = _label;
17002             shortLabel = _shortLabel;
17003             pss = _pss;
17004             swapPss = _swapPss;
17005             id = _id;
17006             hasActivities = false;
17007         }
17008     }
17009
17010     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
17011             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
17012         if (sort && !isCompact) {
17013             Collections.sort(items, new Comparator<MemItem>() {
17014                 @Override
17015                 public int compare(MemItem lhs, MemItem rhs) {
17016                     if (lhs.pss < rhs.pss) {
17017                         return 1;
17018                     } else if (lhs.pss > rhs.pss) {
17019                         return -1;
17020                     }
17021                     return 0;
17022                 }
17023             });
17024         }
17025
17026         for (int i=0; i<items.size(); i++) {
17027             MemItem mi = items.get(i);
17028             if (!isCompact) {
17029                 if (dumpSwapPss) {
17030                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
17031                             mi.label, stringifyKBSize(mi.swapPss));
17032                 } else {
17033                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
17034                 }
17035             } else if (mi.isProc) {
17036                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
17037                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
17038                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
17039                 pw.println(mi.hasActivities ? ",a" : ",e");
17040             } else {
17041                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
17042                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
17043             }
17044             if (mi.subitems != null) {
17045                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
17046                         true, isCompact, dumpSwapPss);
17047             }
17048         }
17049     }
17050
17051     // These are in KB.
17052     static final long[] DUMP_MEM_BUCKETS = new long[] {
17053         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
17054         120*1024, 160*1024, 200*1024,
17055         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
17056         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
17057     };
17058
17059     static final void appendMemBucket(StringBuilder out, long memKB, String label,
17060             boolean stackLike) {
17061         int start = label.lastIndexOf('.');
17062         if (start >= 0) start++;
17063         else start = 0;
17064         int end = label.length();
17065         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17066             if (DUMP_MEM_BUCKETS[i] >= memKB) {
17067                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17068                 out.append(bucket);
17069                 out.append(stackLike ? "MB." : "MB ");
17070                 out.append(label, start, end);
17071                 return;
17072             }
17073         }
17074         out.append(memKB/1024);
17075         out.append(stackLike ? "MB." : "MB ");
17076         out.append(label, start, end);
17077     }
17078
17079     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17080             ProcessList.NATIVE_ADJ,
17081             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17082             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17083             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17084             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17085             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17086             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17087     };
17088     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17089             "Native",
17090             "System", "Persistent", "Persistent Service", "Foreground",
17091             "Visible", "Perceptible",
17092             "Heavy Weight", "Backup",
17093             "A Services", "Home",
17094             "Previous", "B Services", "Cached"
17095     };
17096     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17097             "native",
17098             "sys", "pers", "persvc", "fore",
17099             "vis", "percept",
17100             "heavy", "backup",
17101             "servicea", "home",
17102             "prev", "serviceb", "cached"
17103     };
17104
17105     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17106             long realtime, boolean isCheckinRequest, boolean isCompact) {
17107         if (isCompact) {
17108             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17109         }
17110         if (isCheckinRequest || isCompact) {
17111             // short checkin version
17112             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17113         } else {
17114             pw.println("Applications Memory Usage (in Kilobytes):");
17115             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17116         }
17117     }
17118
17119     private static final int KSM_SHARED = 0;
17120     private static final int KSM_SHARING = 1;
17121     private static final int KSM_UNSHARED = 2;
17122     private static final int KSM_VOLATILE = 3;
17123
17124     private final long[] getKsmInfo() {
17125         long[] longOut = new long[4];
17126         final int[] SINGLE_LONG_FORMAT = new int[] {
17127             PROC_SPACE_TERM| PROC_OUT_LONG
17128         };
17129         long[] longTmp = new long[1];
17130         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17131                 SINGLE_LONG_FORMAT, null, longTmp, null);
17132         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17133         longTmp[0] = 0;
17134         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17135                 SINGLE_LONG_FORMAT, null, longTmp, null);
17136         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17137         longTmp[0] = 0;
17138         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17139                 SINGLE_LONG_FORMAT, null, longTmp, null);
17140         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17141         longTmp[0] = 0;
17142         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17143                 SINGLE_LONG_FORMAT, null, longTmp, null);
17144         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17145         return longOut;
17146     }
17147
17148     private static String stringifySize(long size, int order) {
17149         Locale locale = Locale.US;
17150         switch (order) {
17151             case 1:
17152                 return String.format(locale, "%,13d", size);
17153             case 1024:
17154                 return String.format(locale, "%,9dK", size / 1024);
17155             case 1024 * 1024:
17156                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17157             case 1024 * 1024 * 1024:
17158                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17159             default:
17160                 throw new IllegalArgumentException("Invalid size order");
17161         }
17162     }
17163
17164     private static String stringifyKBSize(long size) {
17165         return stringifySize(size * 1024, 1024);
17166     }
17167
17168     // Update this version number in case you change the 'compact' format
17169     private static final int MEMINFO_COMPACT_VERSION = 1;
17170
17171     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17172             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17173         boolean dumpDetails = false;
17174         boolean dumpFullDetails = false;
17175         boolean dumpDalvik = false;
17176         boolean dumpSummaryOnly = false;
17177         boolean dumpUnreachable = false;
17178         boolean oomOnly = false;
17179         boolean isCompact = false;
17180         boolean localOnly = false;
17181         boolean packages = false;
17182         boolean isCheckinRequest = false;
17183         boolean dumpSwapPss = false;
17184
17185         int opti = 0;
17186         while (opti < args.length) {
17187             String opt = args[opti];
17188             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17189                 break;
17190             }
17191             opti++;
17192             if ("-a".equals(opt)) {
17193                 dumpDetails = true;
17194                 dumpFullDetails = true;
17195                 dumpDalvik = true;
17196                 dumpSwapPss = true;
17197             } else if ("-d".equals(opt)) {
17198                 dumpDalvik = true;
17199             } else if ("-c".equals(opt)) {
17200                 isCompact = true;
17201             } else if ("-s".equals(opt)) {
17202                 dumpDetails = true;
17203                 dumpSummaryOnly = true;
17204             } else if ("-S".equals(opt)) {
17205                 dumpSwapPss = true;
17206             } else if ("--unreachable".equals(opt)) {
17207                 dumpUnreachable = true;
17208             } else if ("--oom".equals(opt)) {
17209                 oomOnly = true;
17210             } else if ("--local".equals(opt)) {
17211                 localOnly = true;
17212             } else if ("--package".equals(opt)) {
17213                 packages = true;
17214             } else if ("--checkin".equals(opt)) {
17215                 isCheckinRequest = true;
17216
17217             } else if ("-h".equals(opt)) {
17218                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17219                 pw.println("  -a: include all available information for each process.");
17220                 pw.println("  -d: include dalvik details.");
17221                 pw.println("  -c: dump in a compact machine-parseable representation.");
17222                 pw.println("  -s: dump only summary of application memory usage.");
17223                 pw.println("  -S: dump also SwapPss.");
17224                 pw.println("  --oom: only show processes organized by oom adj.");
17225                 pw.println("  --local: only collect details locally, don't call process.");
17226                 pw.println("  --package: interpret process arg as package, dumping all");
17227                 pw.println("             processes that have loaded that package.");
17228                 pw.println("  --checkin: dump data for a checkin");
17229                 pw.println("If [process] is specified it can be the name or ");
17230                 pw.println("pid of a specific process to dump.");
17231                 return;
17232             } else {
17233                 pw.println("Unknown argument: " + opt + "; use -h for help");
17234             }
17235         }
17236
17237         long uptime = SystemClock.uptimeMillis();
17238         long realtime = SystemClock.elapsedRealtime();
17239         final long[] tmpLong = new long[1];
17240
17241         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17242         if (procs == null) {
17243             // No Java processes.  Maybe they want to print a native process.
17244             if (args != null && args.length > opti
17245                     && args[opti].charAt(0) != '-') {
17246                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17247                         = new ArrayList<ProcessCpuTracker.Stats>();
17248                 updateCpuStatsNow();
17249                 int findPid = -1;
17250                 try {
17251                     findPid = Integer.parseInt(args[opti]);
17252                 } catch (NumberFormatException e) {
17253                 }
17254                 synchronized (mProcessCpuTracker) {
17255                     final int N = mProcessCpuTracker.countStats();
17256                     for (int i=0; i<N; i++) {
17257                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17258                         if (st.pid == findPid || (st.baseName != null
17259                                 && st.baseName.equals(args[opti]))) {
17260                             nativeProcs.add(st);
17261                         }
17262                     }
17263                 }
17264                 if (nativeProcs.size() > 0) {
17265                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17266                             isCompact);
17267                     Debug.MemoryInfo mi = null;
17268                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17269                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17270                         final int pid = r.pid;
17271                         if (!isCheckinRequest && dumpDetails) {
17272                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17273                         }
17274                         if (mi == null) {
17275                             mi = new Debug.MemoryInfo();
17276                         }
17277                         if (dumpDetails || (!brief && !oomOnly)) {
17278                             Debug.getMemoryInfo(pid, mi);
17279                         } else {
17280                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17281                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17282                         }
17283                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17284                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17285                         if (isCheckinRequest) {
17286                             pw.println();
17287                         }
17288                     }
17289                     return;
17290                 }
17291             }
17292             pw.println("No process found for: " + args[opti]);
17293             return;
17294         }
17295
17296         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17297             dumpDetails = true;
17298         }
17299
17300         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17301
17302         String[] innerArgs = new String[args.length-opti];
17303         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17304
17305         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17306         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17307         long nativePss = 0;
17308         long nativeSwapPss = 0;
17309         long dalvikPss = 0;
17310         long dalvikSwapPss = 0;
17311         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17312                 EmptyArray.LONG;
17313         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17314                 EmptyArray.LONG;
17315         long otherPss = 0;
17316         long otherSwapPss = 0;
17317         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17318         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17319
17320         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17321         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17322         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17323                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17324
17325         long totalPss = 0;
17326         long totalSwapPss = 0;
17327         long cachedPss = 0;
17328         long cachedSwapPss = 0;
17329         boolean hasSwapPss = false;
17330
17331         Debug.MemoryInfo mi = null;
17332         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17333             final ProcessRecord r = procs.get(i);
17334             final IApplicationThread thread;
17335             final int pid;
17336             final int oomAdj;
17337             final boolean hasActivities;
17338             synchronized (this) {
17339                 thread = r.thread;
17340                 pid = r.pid;
17341                 oomAdj = r.getSetAdjWithServices();
17342                 hasActivities = r.activities.size() > 0;
17343             }
17344             if (thread != null) {
17345                 if (!isCheckinRequest && dumpDetails) {
17346                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17347                 }
17348                 if (mi == null) {
17349                     mi = new Debug.MemoryInfo();
17350                 }
17351                 if (dumpDetails || (!brief && !oomOnly)) {
17352                     Debug.getMemoryInfo(pid, mi);
17353                     hasSwapPss = mi.hasSwappedOutPss;
17354                 } else {
17355                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17356                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17357                 }
17358                 if (dumpDetails) {
17359                     if (localOnly) {
17360                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17361                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17362                         if (isCheckinRequest) {
17363                             pw.println();
17364                         }
17365                     } else {
17366                         pw.flush();
17367                         try {
17368                             TransferPipe tp = new TransferPipe();
17369                             try {
17370                                 thread.dumpMemInfo(tp.getWriteFd(),
17371                                         mi, isCheckinRequest, dumpFullDetails,
17372                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17373                                 tp.go(fd);
17374                             } finally {
17375                                 tp.kill();
17376                             }
17377                         } catch (IOException e) {
17378                             if (!isCheckinRequest) {
17379                                 pw.println("Got IoException! " + e);
17380                                 pw.flush();
17381                             }
17382                         } catch (RemoteException e) {
17383                             if (!isCheckinRequest) {
17384                                 pw.println("Got RemoteException! " + e);
17385                                 pw.flush();
17386                             }
17387                         }
17388                     }
17389                 }
17390
17391                 final long myTotalPss = mi.getTotalPss();
17392                 final long myTotalUss = mi.getTotalUss();
17393                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17394
17395                 synchronized (this) {
17396                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17397                         // Record this for posterity if the process has been stable.
17398                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17399                     }
17400                 }
17401
17402                 if (!isCheckinRequest && mi != null) {
17403                     totalPss += myTotalPss;
17404                     totalSwapPss += myTotalSwapPss;
17405                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17406                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17407                             myTotalSwapPss, pid, hasActivities);
17408                     procMems.add(pssItem);
17409                     procMemsMap.put(pid, pssItem);
17410
17411                     nativePss += mi.nativePss;
17412                     nativeSwapPss += mi.nativeSwappedOutPss;
17413                     dalvikPss += mi.dalvikPss;
17414                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17415                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17416                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17417                         dalvikSubitemSwapPss[j] +=
17418                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17419                     }
17420                     otherPss += mi.otherPss;
17421                     otherSwapPss += mi.otherSwappedOutPss;
17422                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17423                         long mem = mi.getOtherPss(j);
17424                         miscPss[j] += mem;
17425                         otherPss -= mem;
17426                         mem = mi.getOtherSwappedOutPss(j);
17427                         miscSwapPss[j] += mem;
17428                         otherSwapPss -= mem;
17429                     }
17430
17431                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17432                         cachedPss += myTotalPss;
17433                         cachedSwapPss += myTotalSwapPss;
17434                     }
17435
17436                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17437                         if (oomIndex == (oomPss.length - 1)
17438                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17439                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17440                             oomPss[oomIndex] += myTotalPss;
17441                             oomSwapPss[oomIndex] += myTotalSwapPss;
17442                             if (oomProcs[oomIndex] == null) {
17443                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17444                             }
17445                             oomProcs[oomIndex].add(pssItem);
17446                             break;
17447                         }
17448                     }
17449                 }
17450             }
17451         }
17452
17453         long nativeProcTotalPss = 0;
17454
17455         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17456             // If we are showing aggregations, also look for native processes to
17457             // include so that our aggregations are more accurate.
17458             updateCpuStatsNow();
17459             mi = null;
17460             synchronized (mProcessCpuTracker) {
17461                 final int N = mProcessCpuTracker.countStats();
17462                 for (int i=0; i<N; i++) {
17463                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17464                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17465                         if (mi == null) {
17466                             mi = new Debug.MemoryInfo();
17467                         }
17468                         if (!brief && !oomOnly) {
17469                             Debug.getMemoryInfo(st.pid, mi);
17470                         } else {
17471                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17472                             mi.nativePrivateDirty = (int)tmpLong[0];
17473                         }
17474
17475                         final long myTotalPss = mi.getTotalPss();
17476                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17477                         totalPss += myTotalPss;
17478                         nativeProcTotalPss += myTotalPss;
17479
17480                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17481                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17482                         procMems.add(pssItem);
17483
17484                         nativePss += mi.nativePss;
17485                         nativeSwapPss += mi.nativeSwappedOutPss;
17486                         dalvikPss += mi.dalvikPss;
17487                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17488                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17489                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17490                             dalvikSubitemSwapPss[j] +=
17491                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17492                         }
17493                         otherPss += mi.otherPss;
17494                         otherSwapPss += mi.otherSwappedOutPss;
17495                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17496                             long mem = mi.getOtherPss(j);
17497                             miscPss[j] += mem;
17498                             otherPss -= mem;
17499                             mem = mi.getOtherSwappedOutPss(j);
17500                             miscSwapPss[j] += mem;
17501                             otherSwapPss -= mem;
17502                         }
17503                         oomPss[0] += myTotalPss;
17504                         oomSwapPss[0] += myTotalSwapPss;
17505                         if (oomProcs[0] == null) {
17506                             oomProcs[0] = new ArrayList<MemItem>();
17507                         }
17508                         oomProcs[0].add(pssItem);
17509                     }
17510                 }
17511             }
17512
17513             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17514
17515             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17516             final int dalvikId = -2;
17517             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17518             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17519             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17520                 String label = Debug.MemoryInfo.getOtherLabel(j);
17521                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17522             }
17523             if (dalvikSubitemPss.length > 0) {
17524                 // Add dalvik subitems.
17525                 for (MemItem memItem : catMems) {
17526                     int memItemStart = 0, memItemEnd = 0;
17527                     if (memItem.id == dalvikId) {
17528                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17529                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17530                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17531                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17532                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17533                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17534                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17535                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17536                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17537                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17538                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17539                     } else {
17540                         continue;  // No subitems, continue.
17541                     }
17542                     memItem.subitems = new ArrayList<MemItem>();
17543                     for (int j=memItemStart; j<=memItemEnd; j++) {
17544                         final String name = Debug.MemoryInfo.getOtherLabel(
17545                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17546                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17547                                 dalvikSubitemSwapPss[j], j));
17548                     }
17549                 }
17550             }
17551
17552             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17553             for (int j=0; j<oomPss.length; j++) {
17554                 if (oomPss[j] != 0) {
17555                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17556                             : DUMP_MEM_OOM_LABEL[j];
17557                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17558                             DUMP_MEM_OOM_ADJ[j]);
17559                     item.subitems = oomProcs[j];
17560                     oomMems.add(item);
17561                 }
17562             }
17563
17564             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17565             if (!brief && !oomOnly && !isCompact) {
17566                 pw.println();
17567                 pw.println("Total PSS by process:");
17568                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17569                 pw.println();
17570             }
17571             if (!isCompact) {
17572                 pw.println("Total PSS by OOM adjustment:");
17573             }
17574             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17575             if (!brief && !oomOnly) {
17576                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17577                 if (!isCompact) {
17578                     out.println();
17579                     out.println("Total PSS by category:");
17580                 }
17581                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17582             }
17583             if (!isCompact) {
17584                 pw.println();
17585             }
17586             MemInfoReader memInfo = new MemInfoReader();
17587             memInfo.readMemInfo();
17588             if (nativeProcTotalPss > 0) {
17589                 synchronized (this) {
17590                     final long cachedKb = memInfo.getCachedSizeKb();
17591                     final long freeKb = memInfo.getFreeSizeKb();
17592                     final long zramKb = memInfo.getZramTotalSizeKb();
17593                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17594                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17595                             kernelKb*1024, nativeProcTotalPss*1024);
17596                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17597                             nativeProcTotalPss);
17598                 }
17599             }
17600             if (!brief) {
17601                 if (!isCompact) {
17602                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17603                     pw.print(" (status ");
17604                     switch (mLastMemoryLevel) {
17605                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17606                             pw.println("normal)");
17607                             break;
17608                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17609                             pw.println("moderate)");
17610                             break;
17611                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17612                             pw.println("low)");
17613                             break;
17614                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17615                             pw.println("critical)");
17616                             break;
17617                         default:
17618                             pw.print(mLastMemoryLevel);
17619                             pw.println(")");
17620                             break;
17621                     }
17622                     pw.print(" Free RAM: ");
17623                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17624                             + memInfo.getFreeSizeKb()));
17625                     pw.print(" (");
17626                     pw.print(stringifyKBSize(cachedPss));
17627                     pw.print(" cached pss + ");
17628                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17629                     pw.print(" cached kernel + ");
17630                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17631                     pw.println(" free)");
17632                 } else {
17633                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17634                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17635                             + memInfo.getFreeSizeKb()); pw.print(",");
17636                     pw.println(totalPss - cachedPss);
17637                 }
17638             }
17639             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17640                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17641                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17642             if (!isCompact) {
17643                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17644                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17645                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17646                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17647                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17648             } else {
17649                 pw.print("lostram,"); pw.println(lostRAM);
17650             }
17651             if (!brief) {
17652                 if (memInfo.getZramTotalSizeKb() != 0) {
17653                     if (!isCompact) {
17654                         pw.print("     ZRAM: ");
17655                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17656                                 pw.print(" physical used for ");
17657                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17658                                         - memInfo.getSwapFreeSizeKb()));
17659                                 pw.print(" in swap (");
17660                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17661                                 pw.println(" total swap)");
17662                     } else {
17663                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17664                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17665                                 pw.println(memInfo.getSwapFreeSizeKb());
17666                     }
17667                 }
17668                 final long[] ksm = getKsmInfo();
17669                 if (!isCompact) {
17670                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17671                             || ksm[KSM_VOLATILE] != 0) {
17672                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17673                                 pw.print(" saved from shared ");
17674                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17675                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17676                                 pw.print(" unshared; ");
17677                                 pw.print(stringifyKBSize(
17678                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17679                     }
17680                     pw.print("   Tuning: ");
17681                     pw.print(ActivityManager.staticGetMemoryClass());
17682                     pw.print(" (large ");
17683                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17684                     pw.print("), oom ");
17685                     pw.print(stringifySize(
17686                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17687                     pw.print(", restore limit ");
17688                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17689                     if (ActivityManager.isLowRamDeviceStatic()) {
17690                         pw.print(" (low-ram)");
17691                     }
17692                     if (ActivityManager.isHighEndGfx()) {
17693                         pw.print(" (high-end-gfx)");
17694                     }
17695                     pw.println();
17696                 } else {
17697                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17698                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17699                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17700                     pw.print("tuning,");
17701                     pw.print(ActivityManager.staticGetMemoryClass());
17702                     pw.print(',');
17703                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17704                     pw.print(',');
17705                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17706                     if (ActivityManager.isLowRamDeviceStatic()) {
17707                         pw.print(",low-ram");
17708                     }
17709                     if (ActivityManager.isHighEndGfx()) {
17710                         pw.print(",high-end-gfx");
17711                     }
17712                     pw.println();
17713                 }
17714             }
17715         }
17716     }
17717
17718     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17719             long memtrack, String name) {
17720         sb.append("  ");
17721         sb.append(ProcessList.makeOomAdjString(oomAdj));
17722         sb.append(' ');
17723         sb.append(ProcessList.makeProcStateString(procState));
17724         sb.append(' ');
17725         ProcessList.appendRamKb(sb, pss);
17726         sb.append(": ");
17727         sb.append(name);
17728         if (memtrack > 0) {
17729             sb.append(" (");
17730             sb.append(stringifyKBSize(memtrack));
17731             sb.append(" memtrack)");
17732         }
17733     }
17734
17735     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17736         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17737         sb.append(" (pid ");
17738         sb.append(mi.pid);
17739         sb.append(") ");
17740         sb.append(mi.adjType);
17741         sb.append('\n');
17742         if (mi.adjReason != null) {
17743             sb.append("                      ");
17744             sb.append(mi.adjReason);
17745             sb.append('\n');
17746         }
17747     }
17748
17749     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17750         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17751         for (int i=0, N=memInfos.size(); i<N; i++) {
17752             ProcessMemInfo mi = memInfos.get(i);
17753             infoMap.put(mi.pid, mi);
17754         }
17755         updateCpuStatsNow();
17756         long[] memtrackTmp = new long[1];
17757         final List<ProcessCpuTracker.Stats> stats;
17758         // Get a list of Stats that have vsize > 0
17759         synchronized (mProcessCpuTracker) {
17760             stats = mProcessCpuTracker.getStats((st) -> {
17761                 return st.vsize > 0;
17762             });
17763         }
17764         final int statsCount = stats.size();
17765         for (int i = 0; i < statsCount; i++) {
17766             ProcessCpuTracker.Stats st = stats.get(i);
17767             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17768             if (pss > 0) {
17769                 if (infoMap.indexOfKey(st.pid) < 0) {
17770                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17771                             ProcessList.NATIVE_ADJ, -1, "native", null);
17772                     mi.pss = pss;
17773                     mi.memtrack = memtrackTmp[0];
17774                     memInfos.add(mi);
17775                 }
17776             }
17777         }
17778
17779         long totalPss = 0;
17780         long totalMemtrack = 0;
17781         for (int i=0, N=memInfos.size(); i<N; i++) {
17782             ProcessMemInfo mi = memInfos.get(i);
17783             if (mi.pss == 0) {
17784                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17785                 mi.memtrack = memtrackTmp[0];
17786             }
17787             totalPss += mi.pss;
17788             totalMemtrack += mi.memtrack;
17789         }
17790         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17791             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17792                 if (lhs.oomAdj != rhs.oomAdj) {
17793                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17794                 }
17795                 if (lhs.pss != rhs.pss) {
17796                     return lhs.pss < rhs.pss ? 1 : -1;
17797                 }
17798                 return 0;
17799             }
17800         });
17801
17802         StringBuilder tag = new StringBuilder(128);
17803         StringBuilder stack = new StringBuilder(128);
17804         tag.append("Low on memory -- ");
17805         appendMemBucket(tag, totalPss, "total", false);
17806         appendMemBucket(stack, totalPss, "total", true);
17807
17808         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17809         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17810         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17811
17812         boolean firstLine = true;
17813         int lastOomAdj = Integer.MIN_VALUE;
17814         long extraNativeRam = 0;
17815         long extraNativeMemtrack = 0;
17816         long cachedPss = 0;
17817         for (int i=0, N=memInfos.size(); i<N; i++) {
17818             ProcessMemInfo mi = memInfos.get(i);
17819
17820             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17821                 cachedPss += mi.pss;
17822             }
17823
17824             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17825                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17826                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17827                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17828                 if (lastOomAdj != mi.oomAdj) {
17829                     lastOomAdj = mi.oomAdj;
17830                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17831                         tag.append(" / ");
17832                     }
17833                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17834                         if (firstLine) {
17835                             stack.append(":");
17836                             firstLine = false;
17837                         }
17838                         stack.append("\n\t at ");
17839                     } else {
17840                         stack.append("$");
17841                     }
17842                 } else {
17843                     tag.append(" ");
17844                     stack.append("$");
17845                 }
17846                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17847                     appendMemBucket(tag, mi.pss, mi.name, false);
17848                 }
17849                 appendMemBucket(stack, mi.pss, mi.name, true);
17850                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17851                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17852                     stack.append("(");
17853                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17854                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17855                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17856                             stack.append(":");
17857                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17858                         }
17859                     }
17860                     stack.append(")");
17861                 }
17862             }
17863
17864             appendMemInfo(fullNativeBuilder, mi);
17865             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17866                 // The short form only has native processes that are >= 512K.
17867                 if (mi.pss >= 512) {
17868                     appendMemInfo(shortNativeBuilder, mi);
17869                 } else {
17870                     extraNativeRam += mi.pss;
17871                     extraNativeMemtrack += mi.memtrack;
17872                 }
17873             } else {
17874                 // Short form has all other details, but if we have collected RAM
17875                 // from smaller native processes let's dump a summary of that.
17876                 if (extraNativeRam > 0) {
17877                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17878                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17879                     shortNativeBuilder.append('\n');
17880                     extraNativeRam = 0;
17881                 }
17882                 appendMemInfo(fullJavaBuilder, mi);
17883             }
17884         }
17885
17886         fullJavaBuilder.append("           ");
17887         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17888         fullJavaBuilder.append(": TOTAL");
17889         if (totalMemtrack > 0) {
17890             fullJavaBuilder.append(" (");
17891             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17892             fullJavaBuilder.append(" memtrack)");
17893         } else {
17894         }
17895         fullJavaBuilder.append("\n");
17896
17897         MemInfoReader memInfo = new MemInfoReader();
17898         memInfo.readMemInfo();
17899         final long[] infos = memInfo.getRawInfo();
17900
17901         StringBuilder memInfoBuilder = new StringBuilder(1024);
17902         Debug.getMemInfo(infos);
17903         memInfoBuilder.append("  MemInfo: ");
17904         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17905         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17906         memInfoBuilder.append(stringifyKBSize(
17907                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17908         memInfoBuilder.append(stringifyKBSize(
17909                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17910         memInfoBuilder.append(stringifyKBSize(
17911                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17912         memInfoBuilder.append("           ");
17913         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17914         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17915         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17916         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17917         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17918             memInfoBuilder.append("  ZRAM: ");
17919             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17920             memInfoBuilder.append(" RAM, ");
17921             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17922             memInfoBuilder.append(" swap total, ");
17923             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17924             memInfoBuilder.append(" swap free\n");
17925         }
17926         final long[] ksm = getKsmInfo();
17927         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17928                 || ksm[KSM_VOLATILE] != 0) {
17929             memInfoBuilder.append("  KSM: ");
17930             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17931             memInfoBuilder.append(" saved from shared ");
17932             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17933             memInfoBuilder.append("\n       ");
17934             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17935             memInfoBuilder.append(" unshared; ");
17936             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17937             memInfoBuilder.append(" volatile\n");
17938         }
17939         memInfoBuilder.append("  Free RAM: ");
17940         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17941                 + memInfo.getFreeSizeKb()));
17942         memInfoBuilder.append("\n");
17943         memInfoBuilder.append("  Used RAM: ");
17944         memInfoBuilder.append(stringifyKBSize(
17945                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17946         memInfoBuilder.append("\n");
17947         memInfoBuilder.append("  Lost RAM: ");
17948         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17949                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17950                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17951         memInfoBuilder.append("\n");
17952         Slog.i(TAG, "Low on memory:");
17953         Slog.i(TAG, shortNativeBuilder.toString());
17954         Slog.i(TAG, fullJavaBuilder.toString());
17955         Slog.i(TAG, memInfoBuilder.toString());
17956
17957         StringBuilder dropBuilder = new StringBuilder(1024);
17958         /*
17959         StringWriter oomSw = new StringWriter();
17960         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17961         StringWriter catSw = new StringWriter();
17962         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17963         String[] emptyArgs = new String[] { };
17964         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17965         oomPw.flush();
17966         String oomString = oomSw.toString();
17967         */
17968         dropBuilder.append("Low on memory:");
17969         dropBuilder.append(stack);
17970         dropBuilder.append('\n');
17971         dropBuilder.append(fullNativeBuilder);
17972         dropBuilder.append(fullJavaBuilder);
17973         dropBuilder.append('\n');
17974         dropBuilder.append(memInfoBuilder);
17975         dropBuilder.append('\n');
17976         /*
17977         dropBuilder.append(oomString);
17978         dropBuilder.append('\n');
17979         */
17980         StringWriter catSw = new StringWriter();
17981         synchronized (ActivityManagerService.this) {
17982             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17983             String[] emptyArgs = new String[] { };
17984             catPw.println();
17985             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17986             catPw.println();
17987             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17988                     false, null).dumpLocked();
17989             catPw.println();
17990             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17991             catPw.flush();
17992         }
17993         dropBuilder.append(catSw.toString());
17994         addErrorToDropBox("lowmem", null, "system_server", null,
17995                 null, tag.toString(), dropBuilder.toString(), null, null);
17996         //Slog.i(TAG, "Sent to dropbox:");
17997         //Slog.i(TAG, dropBuilder.toString());
17998         synchronized (ActivityManagerService.this) {
17999             long now = SystemClock.uptimeMillis();
18000             if (mLastMemUsageReportTime < now) {
18001                 mLastMemUsageReportTime = now;
18002             }
18003         }
18004     }
18005
18006     /**
18007      * Searches array of arguments for the specified string
18008      * @param args array of argument strings
18009      * @param value value to search for
18010      * @return true if the value is contained in the array
18011      */
18012     private static boolean scanArgs(String[] args, String value) {
18013         if (args != null) {
18014             for (String arg : args) {
18015                 if (value.equals(arg)) {
18016                     return true;
18017                 }
18018             }
18019         }
18020         return false;
18021     }
18022
18023     private final boolean removeDyingProviderLocked(ProcessRecord proc,
18024             ContentProviderRecord cpr, boolean always) {
18025         final boolean inLaunching = mLaunchingProviders.contains(cpr);
18026
18027         if (!inLaunching || always) {
18028             synchronized (cpr) {
18029                 cpr.launchingApp = null;
18030                 cpr.notifyAll();
18031             }
18032             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
18033             String names[] = cpr.info.authority.split(";");
18034             for (int j = 0; j < names.length; j++) {
18035                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
18036             }
18037         }
18038
18039         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
18040             ContentProviderConnection conn = cpr.connections.get(i);
18041             if (conn.waiting) {
18042                 // If this connection is waiting for the provider, then we don't
18043                 // need to mess with its process unless we are always removing
18044                 // or for some reason the provider is not currently launching.
18045                 if (inLaunching && !always) {
18046                     continue;
18047                 }
18048             }
18049             ProcessRecord capp = conn.client;
18050             conn.dead = true;
18051             if (conn.stableCount > 0) {
18052                 if (!capp.persistent && capp.thread != null
18053                         && capp.pid != 0
18054                         && capp.pid != MY_PID) {
18055                     capp.kill("depends on provider "
18056                             + cpr.name.flattenToShortString()
18057                             + " in dying proc " + (proc != null ? proc.processName : "??")
18058                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
18059                 }
18060             } else if (capp.thread != null && conn.provider.provider != null) {
18061                 try {
18062                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
18063                 } catch (RemoteException e) {
18064                 }
18065                 // In the protocol here, we don't expect the client to correctly
18066                 // clean up this connection, we'll just remove it.
18067                 cpr.connections.remove(i);
18068                 if (conn.client.conProviders.remove(conn)) {
18069                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18070                 }
18071             }
18072         }
18073
18074         if (inLaunching && always) {
18075             mLaunchingProviders.remove(cpr);
18076         }
18077         return inLaunching;
18078     }
18079
18080     /**
18081      * Main code for cleaning up a process when it has gone away.  This is
18082      * called both as a result of the process dying, or directly when stopping
18083      * a process when running in single process mode.
18084      *
18085      * @return Returns true if the given process has been restarted, so the
18086      * app that was passed in must remain on the process lists.
18087      */
18088     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18089             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18090         if (index >= 0) {
18091             removeLruProcessLocked(app);
18092             ProcessList.remove(app.pid);
18093         }
18094
18095         mProcessesToGc.remove(app);
18096         mPendingPssProcesses.remove(app);
18097
18098         // Dismiss any open dialogs.
18099         if (app.crashDialog != null && !app.forceCrashReport) {
18100             app.crashDialog.dismiss();
18101             app.crashDialog = null;
18102         }
18103         if (app.anrDialog != null) {
18104             app.anrDialog.dismiss();
18105             app.anrDialog = null;
18106         }
18107         if (app.waitDialog != null) {
18108             app.waitDialog.dismiss();
18109             app.waitDialog = null;
18110         }
18111
18112         app.crashing = false;
18113         app.notResponding = false;
18114
18115         app.resetPackageList(mProcessStats);
18116         app.unlinkDeathRecipient();
18117         app.makeInactive(mProcessStats);
18118         app.waitingToKill = null;
18119         app.forcingToImportant = null;
18120         updateProcessForegroundLocked(app, false, false);
18121         app.foregroundActivities = false;
18122         app.hasShownUi = false;
18123         app.treatLikeActivity = false;
18124         app.hasAboveClient = false;
18125         app.hasClientActivities = false;
18126
18127         mServices.killServicesLocked(app, allowRestart);
18128
18129         boolean restart = false;
18130
18131         // Remove published content providers.
18132         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18133             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18134             final boolean always = app.bad || !allowRestart;
18135             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18136             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18137                 // We left the provider in the launching list, need to
18138                 // restart it.
18139                 restart = true;
18140             }
18141
18142             cpr.provider = null;
18143             cpr.proc = null;
18144         }
18145         app.pubProviders.clear();
18146
18147         // Take care of any launching providers waiting for this process.
18148         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18149             restart = true;
18150         }
18151
18152         // Unregister from connected content providers.
18153         if (!app.conProviders.isEmpty()) {
18154             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18155                 ContentProviderConnection conn = app.conProviders.get(i);
18156                 conn.provider.connections.remove(conn);
18157                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18158                         conn.provider.name);
18159             }
18160             app.conProviders.clear();
18161         }
18162
18163         // At this point there may be remaining entries in mLaunchingProviders
18164         // where we were the only one waiting, so they are no longer of use.
18165         // Look for these and clean up if found.
18166         // XXX Commented out for now.  Trying to figure out a way to reproduce
18167         // the actual situation to identify what is actually going on.
18168         if (false) {
18169             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18170                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18171                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18172                     synchronized (cpr) {
18173                         cpr.launchingApp = null;
18174                         cpr.notifyAll();
18175                     }
18176                 }
18177             }
18178         }
18179
18180         skipCurrentReceiverLocked(app);
18181
18182         // Unregister any receivers.
18183         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18184             removeReceiverLocked(app.receivers.valueAt(i));
18185         }
18186         app.receivers.clear();
18187
18188         // If the app is undergoing backup, tell the backup manager about it
18189         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18190             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18191                     + mBackupTarget.appInfo + " died during backup");
18192             mHandler.post(new Runnable() {
18193                 @Override
18194                 public void run(){
18195                     try {
18196                         IBackupManager bm = IBackupManager.Stub.asInterface(
18197                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18198                         bm.agentDisconnected(app.info.packageName);
18199                     } catch (RemoteException e) {
18200                         // can't happen; backup manager is local
18201                     }
18202                 }
18203             });
18204         }
18205
18206         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18207             ProcessChangeItem item = mPendingProcessChanges.get(i);
18208             if (item.pid == app.pid) {
18209                 mPendingProcessChanges.remove(i);
18210                 mAvailProcessChanges.add(item);
18211             }
18212         }
18213         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18214                 null).sendToTarget();
18215
18216         // If the caller is restarting this app, then leave it in its
18217         // current lists and let the caller take care of it.
18218         if (restarting) {
18219             return false;
18220         }
18221
18222         if (!app.persistent || app.isolated) {
18223             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18224                     "Removing non-persistent process during cleanup: " + app);
18225             if (!replacingPid) {
18226                 removeProcessNameLocked(app.processName, app.uid, app);
18227             }
18228             if (mHeavyWeightProcess == app) {
18229                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18230                         mHeavyWeightProcess.userId, 0));
18231                 mHeavyWeightProcess = null;
18232             }
18233         } else if (!app.removed) {
18234             // This app is persistent, so we need to keep its record around.
18235             // If it is not already on the pending app list, add it there
18236             // and start a new process for it.
18237             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18238                 mPersistentStartingProcesses.add(app);
18239                 restart = true;
18240             }
18241         }
18242         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18243                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18244         mProcessesOnHold.remove(app);
18245
18246         if (app == mHomeProcess) {
18247             mHomeProcess = null;
18248         }
18249         if (app == mPreviousProcess) {
18250             mPreviousProcess = null;
18251         }
18252
18253         if (restart && !app.isolated) {
18254             // We have components that still need to be running in the
18255             // process, so re-launch it.
18256             if (index < 0) {
18257                 ProcessList.remove(app.pid);
18258             }
18259             addProcessNameLocked(app);
18260             startProcessLocked(app, "restart", app.processName);
18261             return true;
18262         } else if (app.pid > 0 && app.pid != MY_PID) {
18263             // Goodbye!
18264             boolean removed;
18265             synchronized (mPidsSelfLocked) {
18266                 mPidsSelfLocked.remove(app.pid);
18267                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18268             }
18269             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18270             if (app.isolated) {
18271                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18272             }
18273             app.setPid(0);
18274         }
18275         return false;
18276     }
18277
18278     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18279         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18280             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18281             if (cpr.launchingApp == app) {
18282                 return true;
18283             }
18284         }
18285         return false;
18286     }
18287
18288     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18289         // Look through the content providers we are waiting to have launched,
18290         // and if any run in this process then either schedule a restart of
18291         // the process or kill the client waiting for it if this process has
18292         // gone bad.
18293         boolean restart = false;
18294         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18295             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18296             if (cpr.launchingApp == app) {
18297                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18298                     restart = true;
18299                 } else {
18300                     removeDyingProviderLocked(app, cpr, true);
18301                 }
18302             }
18303         }
18304         return restart;
18305     }
18306
18307     // =========================================================
18308     // SERVICES
18309     // =========================================================
18310
18311     @Override
18312     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18313             int flags) {
18314         enforceNotIsolatedCaller("getServices");
18315
18316         final int callingUid = Binder.getCallingUid();
18317         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18318             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18319         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18320             callingUid);
18321         synchronized (this) {
18322             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18323                 allowed, canInteractAcrossUsers);
18324         }
18325     }
18326
18327     @Override
18328     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18329         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18330         synchronized (this) {
18331             return mServices.getRunningServiceControlPanelLocked(name);
18332         }
18333     }
18334
18335     @Override
18336     public ComponentName startService(IApplicationThread caller, Intent service,
18337             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18338             throws TransactionTooLargeException {
18339         enforceNotIsolatedCaller("startService");
18340         // Refuse possible leaked file descriptors
18341         if (service != null && service.hasFileDescriptors() == true) {
18342             throw new IllegalArgumentException("File descriptors passed in Intent");
18343         }
18344
18345         if (callingPackage == null) {
18346             throw new IllegalArgumentException("callingPackage cannot be null");
18347         }
18348
18349         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18350                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18351         synchronized(this) {
18352             final int callingPid = Binder.getCallingPid();
18353             final int callingUid = Binder.getCallingUid();
18354             final long origId = Binder.clearCallingIdentity();
18355             ComponentName res;
18356             try {
18357                 res = mServices.startServiceLocked(caller, service,
18358                         resolvedType, callingPid, callingUid,
18359                         requireForeground, callingPackage, userId);
18360             } finally {
18361                 Binder.restoreCallingIdentity(origId);
18362             }
18363             return res;
18364         }
18365     }
18366
18367     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18368             boolean fgRequired, String callingPackage, int userId)
18369             throws TransactionTooLargeException {
18370         synchronized(this) {
18371             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18372                     "startServiceInPackage: " + service + " type=" + resolvedType);
18373             final long origId = Binder.clearCallingIdentity();
18374             ComponentName res;
18375             try {
18376                 res = mServices.startServiceLocked(null, service,
18377                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18378             } finally {
18379                 Binder.restoreCallingIdentity(origId);
18380             }
18381             return res;
18382         }
18383     }
18384
18385     @Override
18386     public int stopService(IApplicationThread caller, Intent service,
18387             String resolvedType, int userId) {
18388         enforceNotIsolatedCaller("stopService");
18389         // Refuse possible leaked file descriptors
18390         if (service != null && service.hasFileDescriptors() == true) {
18391             throw new IllegalArgumentException("File descriptors passed in Intent");
18392         }
18393
18394         synchronized(this) {
18395             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18396         }
18397     }
18398
18399     @Override
18400     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18401         enforceNotIsolatedCaller("peekService");
18402         // Refuse possible leaked file descriptors
18403         if (service != null && service.hasFileDescriptors() == true) {
18404             throw new IllegalArgumentException("File descriptors passed in Intent");
18405         }
18406
18407         if (callingPackage == null) {
18408             throw new IllegalArgumentException("callingPackage cannot be null");
18409         }
18410
18411         synchronized(this) {
18412             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18413         }
18414     }
18415
18416     @Override
18417     public boolean stopServiceToken(ComponentName className, IBinder token,
18418             int startId) {
18419         synchronized(this) {
18420             return mServices.stopServiceTokenLocked(className, token, startId);
18421         }
18422     }
18423
18424     @Override
18425     public void setServiceForeground(ComponentName className, IBinder token,
18426             int id, Notification notification, int flags) {
18427         synchronized(this) {
18428             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18429         }
18430     }
18431
18432     @Override
18433     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18434             boolean requireFull, String name, String callerPackage) {
18435         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18436                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18437     }
18438
18439     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18440             String className, int flags) {
18441         boolean result = false;
18442         // For apps that don't have pre-defined UIDs, check for permission
18443         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18444             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18445                 if (ActivityManager.checkUidPermission(
18446                         INTERACT_ACROSS_USERS,
18447                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18448                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18449                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18450                             + " requests FLAG_SINGLE_USER, but app does not hold "
18451                             + INTERACT_ACROSS_USERS;
18452                     Slog.w(TAG, msg);
18453                     throw new SecurityException(msg);
18454                 }
18455                 // Permission passed
18456                 result = true;
18457             }
18458         } else if ("system".equals(componentProcessName)) {
18459             result = true;
18460         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18461             // Phone app and persistent apps are allowed to export singleuser providers.
18462             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18463                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18464         }
18465         if (DEBUG_MU) Slog.v(TAG_MU,
18466                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18467                 + Integer.toHexString(flags) + ") = " + result);
18468         return result;
18469     }
18470
18471     /**
18472      * Checks to see if the caller is in the same app as the singleton
18473      * component, or the component is in a special app. It allows special apps
18474      * to export singleton components but prevents exporting singleton
18475      * components for regular apps.
18476      */
18477     boolean isValidSingletonCall(int callingUid, int componentUid) {
18478         int componentAppId = UserHandle.getAppId(componentUid);
18479         return UserHandle.isSameApp(callingUid, componentUid)
18480                 || componentAppId == SYSTEM_UID
18481                 || componentAppId == PHONE_UID
18482                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18483                         == PackageManager.PERMISSION_GRANTED;
18484     }
18485
18486     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18487             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18488             int userId) throws TransactionTooLargeException {
18489         enforceNotIsolatedCaller("bindService");
18490
18491         // Refuse possible leaked file descriptors
18492         if (service != null && service.hasFileDescriptors() == true) {
18493             throw new IllegalArgumentException("File descriptors passed in Intent");
18494         }
18495
18496         if (callingPackage == null) {
18497             throw new IllegalArgumentException("callingPackage cannot be null");
18498         }
18499
18500         synchronized(this) {
18501             return mServices.bindServiceLocked(caller, token, service,
18502                     resolvedType, connection, flags, callingPackage, userId);
18503         }
18504     }
18505
18506     public boolean unbindService(IServiceConnection connection) {
18507         synchronized (this) {
18508             return mServices.unbindServiceLocked(connection);
18509         }
18510     }
18511
18512     public void publishService(IBinder token, Intent intent, IBinder service) {
18513         // Refuse possible leaked file descriptors
18514         if (intent != null && intent.hasFileDescriptors() == true) {
18515             throw new IllegalArgumentException("File descriptors passed in Intent");
18516         }
18517
18518         synchronized(this) {
18519             if (!(token instanceof ServiceRecord)) {
18520                 throw new IllegalArgumentException("Invalid service token");
18521             }
18522             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18523         }
18524     }
18525
18526     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18527         // Refuse possible leaked file descriptors
18528         if (intent != null && intent.hasFileDescriptors() == true) {
18529             throw new IllegalArgumentException("File descriptors passed in Intent");
18530         }
18531
18532         synchronized(this) {
18533             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18534         }
18535     }
18536
18537     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18538         synchronized(this) {
18539             if (!(token instanceof ServiceRecord)) {
18540                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18541                 throw new IllegalArgumentException("Invalid service token");
18542             }
18543             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18544         }
18545     }
18546
18547     // =========================================================
18548     // BACKUP AND RESTORE
18549     // =========================================================
18550
18551     // Cause the target app to be launched if necessary and its backup agent
18552     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18553     // activity manager to announce its creation.
18554     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18555         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18556         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18557
18558         IPackageManager pm = AppGlobals.getPackageManager();
18559         ApplicationInfo app = null;
18560         try {
18561             app = pm.getApplicationInfo(packageName, 0, userId);
18562         } catch (RemoteException e) {
18563             // can't happen; package manager is process-local
18564         }
18565         if (app == null) {
18566             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18567             return false;
18568         }
18569
18570         int oldBackupUid;
18571         int newBackupUid;
18572
18573         synchronized(this) {
18574             // !!! TODO: currently no check here that we're already bound
18575             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18576             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18577             synchronized (stats) {
18578                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18579             }
18580
18581             // Backup agent is now in use, its package can't be stopped.
18582             try {
18583                 AppGlobals.getPackageManager().setPackageStoppedState(
18584                         app.packageName, false, UserHandle.getUserId(app.uid));
18585             } catch (RemoteException e) {
18586             } catch (IllegalArgumentException e) {
18587                 Slog.w(TAG, "Failed trying to unstop package "
18588                         + app.packageName + ": " + e);
18589             }
18590
18591             BackupRecord r = new BackupRecord(ss, app, backupMode);
18592             ComponentName hostingName =
18593                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18594                             ? new ComponentName(app.packageName, app.backupAgentName)
18595                             : new ComponentName("android", "FullBackupAgent");
18596             // startProcessLocked() returns existing proc's record if it's already running
18597             ProcessRecord proc = startProcessLocked(app.processName, app,
18598                     false, 0, "backup", hostingName, false, false, false);
18599             if (proc == null) {
18600                 Slog.e(TAG, "Unable to start backup agent process " + r);
18601                 return false;
18602             }
18603
18604             // If the app is a regular app (uid >= 10000) and not the system server or phone
18605             // process, etc, then mark it as being in full backup so that certain calls to the
18606             // process can be blocked. This is not reset to false anywhere because we kill the
18607             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18608             if (UserHandle.isApp(app.uid) &&
18609                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18610                 proc.inFullBackup = true;
18611             }
18612             r.app = proc;
18613             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18614             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18615             mBackupTarget = r;
18616             mBackupAppName = app.packageName;
18617
18618             // Try not to kill the process during backup
18619             updateOomAdjLocked(proc, true);
18620
18621             // If the process is already attached, schedule the creation of the backup agent now.
18622             // If it is not yet live, this will be done when it attaches to the framework.
18623             if (proc.thread != null) {
18624                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18625                 try {
18626                     proc.thread.scheduleCreateBackupAgent(app,
18627                             compatibilityInfoForPackageLocked(app), backupMode);
18628                 } catch (RemoteException e) {
18629                     // Will time out on the backup manager side
18630                 }
18631             } else {
18632                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18633             }
18634             // Invariants: at this point, the target app process exists and the application
18635             // is either already running or in the process of coming up.  mBackupTarget and
18636             // mBackupAppName describe the app, so that when it binds back to the AM we
18637             // know that it's scheduled for a backup-agent operation.
18638         }
18639
18640         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18641         if (oldBackupUid != -1) {
18642             js.removeBackingUpUid(oldBackupUid);
18643         }
18644         if (newBackupUid != -1) {
18645             js.addBackingUpUid(newBackupUid);
18646         }
18647
18648         return true;
18649     }
18650
18651     @Override
18652     public void clearPendingBackup() {
18653         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18654         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18655
18656         synchronized (this) {
18657             mBackupTarget = null;
18658             mBackupAppName = null;
18659         }
18660
18661         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18662         js.clearAllBackingUpUids();
18663     }
18664
18665     // A backup agent has just come up
18666     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18667         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18668                 + " = " + agent);
18669
18670         synchronized(this) {
18671             if (!agentPackageName.equals(mBackupAppName)) {
18672                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18673                 return;
18674             }
18675         }
18676
18677         long oldIdent = Binder.clearCallingIdentity();
18678         try {
18679             IBackupManager bm = IBackupManager.Stub.asInterface(
18680                     ServiceManager.getService(Context.BACKUP_SERVICE));
18681             bm.agentConnected(agentPackageName, agent);
18682         } catch (RemoteException e) {
18683             // can't happen; the backup manager service is local
18684         } catch (Exception e) {
18685             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18686             e.printStackTrace();
18687         } finally {
18688             Binder.restoreCallingIdentity(oldIdent);
18689         }
18690     }
18691
18692     // done with this agent
18693     public void unbindBackupAgent(ApplicationInfo appInfo) {
18694         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18695         if (appInfo == null) {
18696             Slog.w(TAG, "unbind backup agent for null app");
18697             return;
18698         }
18699
18700         int oldBackupUid;
18701
18702         synchronized(this) {
18703             try {
18704                 if (mBackupAppName == null) {
18705                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18706                     return;
18707                 }
18708
18709                 if (!mBackupAppName.equals(appInfo.packageName)) {
18710                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18711                     return;
18712                 }
18713
18714                 // Not backing this app up any more; reset its OOM adjustment
18715                 final ProcessRecord proc = mBackupTarget.app;
18716                 updateOomAdjLocked(proc, true);
18717                 proc.inFullBackup = false;
18718
18719                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18720
18721                 // If the app crashed during backup, 'thread' will be null here
18722                 if (proc.thread != null) {
18723                     try {
18724                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18725                                 compatibilityInfoForPackageLocked(appInfo));
18726                     } catch (Exception e) {
18727                         Slog.e(TAG, "Exception when unbinding backup agent:");
18728                         e.printStackTrace();
18729                     }
18730                 }
18731             } finally {
18732                 mBackupTarget = null;
18733                 mBackupAppName = null;
18734             }
18735         }
18736
18737         if (oldBackupUid != -1) {
18738             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18739             js.removeBackingUpUid(oldBackupUid);
18740         }
18741     }
18742
18743     // =========================================================
18744     // BROADCASTS
18745     // =========================================================
18746
18747     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18748         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18749             return false;
18750         }
18751         // Easy case -- we have the app's ProcessRecord.
18752         if (record != null) {
18753             return record.info.isInstantApp();
18754         }
18755         // Otherwise check with PackageManager.
18756         if (callerPackage == null) {
18757             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18758             throw new IllegalArgumentException("Calling application did not provide package name");
18759         }
18760         mAppOpsService.checkPackage(uid, callerPackage);
18761         try {
18762             IPackageManager pm = AppGlobals.getPackageManager();
18763             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18764         } catch (RemoteException e) {
18765             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18766             return true;
18767         }
18768     }
18769
18770     boolean isPendingBroadcastProcessLocked(int pid) {
18771         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18772                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18773     }
18774
18775     void skipPendingBroadcastLocked(int pid) {
18776             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18777             for (BroadcastQueue queue : mBroadcastQueues) {
18778                 queue.skipPendingBroadcastLocked(pid);
18779             }
18780     }
18781
18782     // The app just attached; send any pending broadcasts that it should receive
18783     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18784         boolean didSomething = false;
18785         for (BroadcastQueue queue : mBroadcastQueues) {
18786             didSomething |= queue.sendPendingBroadcastsLocked(app);
18787         }
18788         return didSomething;
18789     }
18790
18791     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18792             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18793             int flags) {
18794         enforceNotIsolatedCaller("registerReceiver");
18795         ArrayList<Intent> stickyIntents = null;
18796         ProcessRecord callerApp = null;
18797         final boolean visibleToInstantApps
18798                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18799         int callingUid;
18800         int callingPid;
18801         boolean instantApp;
18802         synchronized(this) {
18803             if (caller != null) {
18804                 callerApp = getRecordForAppLocked(caller);
18805                 if (callerApp == null) {
18806                     throw new SecurityException(
18807                             "Unable to find app for caller " + caller
18808                             + " (pid=" + Binder.getCallingPid()
18809                             + ") when registering receiver " + receiver);
18810                 }
18811                 if (callerApp.info.uid != SYSTEM_UID &&
18812                         !callerApp.pkgList.containsKey(callerPackage) &&
18813                         !"android".equals(callerPackage)) {
18814                     throw new SecurityException("Given caller package " + callerPackage
18815                             + " is not running in process " + callerApp);
18816                 }
18817                 callingUid = callerApp.info.uid;
18818                 callingPid = callerApp.pid;
18819             } else {
18820                 callerPackage = null;
18821                 callingUid = Binder.getCallingUid();
18822                 callingPid = Binder.getCallingPid();
18823             }
18824
18825             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18826             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18827                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18828
18829             Iterator<String> actions = filter.actionsIterator();
18830             if (actions == null) {
18831                 ArrayList<String> noAction = new ArrayList<String>(1);
18832                 noAction.add(null);
18833                 actions = noAction.iterator();
18834             }
18835
18836             // Collect stickies of users
18837             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18838             while (actions.hasNext()) {
18839                 String action = actions.next();
18840                 for (int id : userIds) {
18841                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18842                     if (stickies != null) {
18843                         ArrayList<Intent> intents = stickies.get(action);
18844                         if (intents != null) {
18845                             if (stickyIntents == null) {
18846                                 stickyIntents = new ArrayList<Intent>();
18847                             }
18848                             stickyIntents.addAll(intents);
18849                         }
18850                     }
18851                 }
18852             }
18853         }
18854
18855         ArrayList<Intent> allSticky = null;
18856         if (stickyIntents != null) {
18857             final ContentResolver resolver = mContext.getContentResolver();
18858             // Look for any matching sticky broadcasts...
18859             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18860                 Intent intent = stickyIntents.get(i);
18861                 // Don't provided intents that aren't available to instant apps.
18862                 if (instantApp &&
18863                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18864                     continue;
18865                 }
18866                 // If intent has scheme "content", it will need to acccess
18867                 // provider that needs to lock mProviderMap in ActivityThread
18868                 // and also it may need to wait application response, so we
18869                 // cannot lock ActivityManagerService here.
18870                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18871                     if (allSticky == null) {
18872                         allSticky = new ArrayList<Intent>();
18873                     }
18874                     allSticky.add(intent);
18875                 }
18876             }
18877         }
18878
18879         // The first sticky in the list is returned directly back to the client.
18880         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18881         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18882         if (receiver == null) {
18883             return sticky;
18884         }
18885
18886         synchronized (this) {
18887             if (callerApp != null && (callerApp.thread == null
18888                     || callerApp.thread.asBinder() != caller.asBinder())) {
18889                 // Original caller already died
18890                 return null;
18891             }
18892             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18893             if (rl == null) {
18894                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18895                         userId, receiver);
18896                 if (rl.app != null) {
18897                     rl.app.receivers.add(rl);
18898                 } else {
18899                     try {
18900                         receiver.asBinder().linkToDeath(rl, 0);
18901                     } catch (RemoteException e) {
18902                         return sticky;
18903                     }
18904                     rl.linkedToDeath = true;
18905                 }
18906                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18907             } else if (rl.uid != callingUid) {
18908                 throw new IllegalArgumentException(
18909                         "Receiver requested to register for uid " + callingUid
18910                         + " was previously registered for uid " + rl.uid
18911                         + " callerPackage is " + callerPackage);
18912             } else if (rl.pid != callingPid) {
18913                 throw new IllegalArgumentException(
18914                         "Receiver requested to register for pid " + callingPid
18915                         + " was previously registered for pid " + rl.pid
18916                         + " callerPackage is " + callerPackage);
18917             } else if (rl.userId != userId) {
18918                 throw new IllegalArgumentException(
18919                         "Receiver requested to register for user " + userId
18920                         + " was previously registered for user " + rl.userId
18921                         + " callerPackage is " + callerPackage);
18922             }
18923             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18924                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18925             rl.add(bf);
18926             if (!bf.debugCheck()) {
18927                 Slog.w(TAG, "==> For Dynamic broadcast");
18928             }
18929             mReceiverResolver.addFilter(bf);
18930
18931             // Enqueue broadcasts for all existing stickies that match
18932             // this filter.
18933             if (allSticky != null) {
18934                 ArrayList receivers = new ArrayList();
18935                 receivers.add(bf);
18936
18937                 final int stickyCount = allSticky.size();
18938                 for (int i = 0; i < stickyCount; i++) {
18939                     Intent intent = allSticky.get(i);
18940                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18941                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18942                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18943                             null, 0, null, null, false, true, true, -1);
18944                     queue.enqueueParallelBroadcastLocked(r);
18945                     queue.scheduleBroadcastsLocked();
18946                 }
18947             }
18948
18949             return sticky;
18950         }
18951     }
18952
18953     public void unregisterReceiver(IIntentReceiver receiver) {
18954         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18955
18956         final long origId = Binder.clearCallingIdentity();
18957         try {
18958             boolean doTrim = false;
18959
18960             synchronized(this) {
18961                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18962                 if (rl != null) {
18963                     final BroadcastRecord r = rl.curBroadcast;
18964                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18965                         final boolean doNext = r.queue.finishReceiverLocked(
18966                                 r, r.resultCode, r.resultData, r.resultExtras,
18967                                 r.resultAbort, false);
18968                         if (doNext) {
18969                             doTrim = true;
18970                             r.queue.processNextBroadcast(false);
18971                         }
18972                     }
18973
18974                     if (rl.app != null) {
18975                         rl.app.receivers.remove(rl);
18976                     }
18977                     removeReceiverLocked(rl);
18978                     if (rl.linkedToDeath) {
18979                         rl.linkedToDeath = false;
18980                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18981                     }
18982                 }
18983             }
18984
18985             // If we actually concluded any broadcasts, we might now be able
18986             // to trim the recipients' apps from our working set
18987             if (doTrim) {
18988                 trimApplications();
18989                 return;
18990             }
18991
18992         } finally {
18993             Binder.restoreCallingIdentity(origId);
18994         }
18995     }
18996
18997     void removeReceiverLocked(ReceiverList rl) {
18998         mRegisteredReceivers.remove(rl.receiver.asBinder());
18999         for (int i = rl.size() - 1; i >= 0; i--) {
19000             mReceiverResolver.removeFilter(rl.get(i));
19001         }
19002     }
19003
19004     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
19005         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19006             ProcessRecord r = mLruProcesses.get(i);
19007             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
19008                 try {
19009                     r.thread.dispatchPackageBroadcast(cmd, packages);
19010                 } catch (RemoteException ex) {
19011                 }
19012             }
19013         }
19014     }
19015
19016     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
19017             int callingUid, int[] users) {
19018         // TODO: come back and remove this assumption to triage all broadcasts
19019         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
19020
19021         List<ResolveInfo> receivers = null;
19022         try {
19023             HashSet<ComponentName> singleUserReceivers = null;
19024             boolean scannedFirstReceivers = false;
19025             for (int user : users) {
19026                 // Skip users that have Shell restrictions, with exception of always permitted
19027                 // Shell broadcasts
19028                 if (callingUid == SHELL_UID
19029                         && mUserController.hasUserRestriction(
19030                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
19031                         && !isPermittedShellBroadcast(intent)) {
19032                     continue;
19033                 }
19034                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
19035                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
19036                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
19037                     // If this is not the system user, we need to check for
19038                     // any receivers that should be filtered out.
19039                     for (int i=0; i<newReceivers.size(); i++) {
19040                         ResolveInfo ri = newReceivers.get(i);
19041                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
19042                             newReceivers.remove(i);
19043                             i--;
19044                         }
19045                     }
19046                 }
19047                 if (newReceivers != null && newReceivers.size() == 0) {
19048                     newReceivers = null;
19049                 }
19050                 if (receivers == null) {
19051                     receivers = newReceivers;
19052                 } else if (newReceivers != null) {
19053                     // We need to concatenate the additional receivers
19054                     // found with what we have do far.  This would be easy,
19055                     // but we also need to de-dup any receivers that are
19056                     // singleUser.
19057                     if (!scannedFirstReceivers) {
19058                         // Collect any single user receivers we had already retrieved.
19059                         scannedFirstReceivers = true;
19060                         for (int i=0; i<receivers.size(); i++) {
19061                             ResolveInfo ri = receivers.get(i);
19062                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19063                                 ComponentName cn = new ComponentName(
19064                                         ri.activityInfo.packageName, ri.activityInfo.name);
19065                                 if (singleUserReceivers == null) {
19066                                     singleUserReceivers = new HashSet<ComponentName>();
19067                                 }
19068                                 singleUserReceivers.add(cn);
19069                             }
19070                         }
19071                     }
19072                     // Add the new results to the existing results, tracking
19073                     // and de-dupping single user receivers.
19074                     for (int i=0; i<newReceivers.size(); i++) {
19075                         ResolveInfo ri = newReceivers.get(i);
19076                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19077                             ComponentName cn = new ComponentName(
19078                                     ri.activityInfo.packageName, ri.activityInfo.name);
19079                             if (singleUserReceivers == null) {
19080                                 singleUserReceivers = new HashSet<ComponentName>();
19081                             }
19082                             if (!singleUserReceivers.contains(cn)) {
19083                                 singleUserReceivers.add(cn);
19084                                 receivers.add(ri);
19085                             }
19086                         } else {
19087                             receivers.add(ri);
19088                         }
19089                     }
19090                 }
19091             }
19092         } catch (RemoteException ex) {
19093             // pm is in same process, this will never happen.
19094         }
19095         return receivers;
19096     }
19097
19098     private boolean isPermittedShellBroadcast(Intent intent) {
19099         // remote bugreport should always be allowed to be taken
19100         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19101     }
19102
19103     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19104             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19105         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19106             // Don't yell about broadcasts sent via shell
19107             return;
19108         }
19109
19110         final String action = intent.getAction();
19111         if (isProtectedBroadcast
19112                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19113                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19114                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19115                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19116                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19117                 || Intent.ACTION_MASTER_CLEAR.equals(action)
19118                 || Intent.ACTION_FACTORY_RESET.equals(action)
19119                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19120                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19121                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19122                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19123                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19124                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19125                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19126             // Broadcast is either protected, or it's a public action that
19127             // we've relaxed, so it's fine for system internals to send.
19128             return;
19129         }
19130
19131         // This broadcast may be a problem...  but there are often system components that
19132         // want to send an internal broadcast to themselves, which is annoying to have to
19133         // explicitly list each action as a protected broadcast, so we will check for that
19134         // one safe case and allow it: an explicit broadcast, only being received by something
19135         // that has protected itself.
19136         if (receivers != null && receivers.size() > 0
19137                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19138             boolean allProtected = true;
19139             for (int i = receivers.size()-1; i >= 0; i--) {
19140                 Object target = receivers.get(i);
19141                 if (target instanceof ResolveInfo) {
19142                     ResolveInfo ri = (ResolveInfo)target;
19143                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19144                         allProtected = false;
19145                         break;
19146                     }
19147                 } else {
19148                     BroadcastFilter bf = (BroadcastFilter)target;
19149                     if (bf.requiredPermission == null) {
19150                         allProtected = false;
19151                         break;
19152                     }
19153                 }
19154             }
19155             if (allProtected) {
19156                 // All safe!
19157                 return;
19158             }
19159         }
19160
19161         // The vast majority of broadcasts sent from system internals
19162         // should be protected to avoid security holes, so yell loudly
19163         // to ensure we examine these cases.
19164         if (callerApp != null) {
19165             Log.wtf(TAG, "Sending non-protected broadcast " + action
19166                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19167                     new Throwable());
19168         } else {
19169             Log.wtf(TAG, "Sending non-protected broadcast " + action
19170                             + " from system uid " + UserHandle.formatUid(callingUid)
19171                             + " pkg " + callerPackage,
19172                     new Throwable());
19173         }
19174     }
19175
19176     final int broadcastIntentLocked(ProcessRecord callerApp,
19177             String callerPackage, Intent intent, String resolvedType,
19178             IIntentReceiver resultTo, int resultCode, String resultData,
19179             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19180             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19181         intent = new Intent(intent);
19182
19183         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19184         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19185         if (callerInstantApp) {
19186             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19187         }
19188
19189         // By default broadcasts do not go to stopped apps.
19190         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19191
19192         // If we have not finished booting, don't allow this to launch new processes.
19193         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19194             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19195         }
19196
19197         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19198                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19199                 + " ordered=" + ordered + " userid=" + userId);
19200         if ((resultTo != null) && !ordered) {
19201             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19202         }
19203
19204         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19205                 ALLOW_NON_FULL, "broadcast", callerPackage);
19206
19207         // Make sure that the user who is receiving this broadcast is running.
19208         // If not, we will just skip it. Make an exception for shutdown broadcasts
19209         // and upgrade steps.
19210
19211         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19212             if ((callingUid != SYSTEM_UID
19213                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19214                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19215                 Slog.w(TAG, "Skipping broadcast of " + intent
19216                         + ": user " + userId + " is stopped");
19217                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19218             }
19219         }
19220
19221         BroadcastOptions brOptions = null;
19222         if (bOptions != null) {
19223             brOptions = new BroadcastOptions(bOptions);
19224             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19225                 // See if the caller is allowed to do this.  Note we are checking against
19226                 // the actual real caller (not whoever provided the operation as say a
19227                 // PendingIntent), because that who is actually supplied the arguments.
19228                 if (checkComponentPermission(
19229                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19230                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19231                         != PackageManager.PERMISSION_GRANTED) {
19232                     String msg = "Permission Denial: " + intent.getAction()
19233                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19234                             + ", uid=" + callingUid + ")"
19235                             + " requires "
19236                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19237                     Slog.w(TAG, msg);
19238                     throw new SecurityException(msg);
19239                 }
19240             }
19241         }
19242
19243         // Verify that protected broadcasts are only being sent by system code,
19244         // and that system code is only sending protected broadcasts.
19245         final String action = intent.getAction();
19246         final boolean isProtectedBroadcast;
19247         try {
19248             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19249         } catch (RemoteException e) {
19250             Slog.w(TAG, "Remote exception", e);
19251             return ActivityManager.BROADCAST_SUCCESS;
19252         }
19253
19254         final boolean isCallerSystem;
19255         switch (UserHandle.getAppId(callingUid)) {
19256             case ROOT_UID:
19257             case SYSTEM_UID:
19258             case PHONE_UID:
19259             case BLUETOOTH_UID:
19260             case NFC_UID:
19261                 isCallerSystem = true;
19262                 break;
19263             default:
19264                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19265                 break;
19266         }
19267
19268         // First line security check before anything else: stop non-system apps from
19269         // sending protected broadcasts.
19270         if (!isCallerSystem) {
19271             if (isProtectedBroadcast) {
19272                 String msg = "Permission Denial: not allowed to send broadcast "
19273                         + action + " from pid="
19274                         + callingPid + ", uid=" + callingUid;
19275                 Slog.w(TAG, msg);
19276                 throw new SecurityException(msg);
19277
19278             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19279                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19280                 // Special case for compatibility: we don't want apps to send this,
19281                 // but historically it has not been protected and apps may be using it
19282                 // to poke their own app widget.  So, instead of making it protected,
19283                 // just limit it to the caller.
19284                 if (callerPackage == null) {
19285                     String msg = "Permission Denial: not allowed to send broadcast "
19286                             + action + " from unknown caller.";
19287                     Slog.w(TAG, msg);
19288                     throw new SecurityException(msg);
19289                 } else if (intent.getComponent() != null) {
19290                     // They are good enough to send to an explicit component...  verify
19291                     // it is being sent to the calling app.
19292                     if (!intent.getComponent().getPackageName().equals(
19293                             callerPackage)) {
19294                         String msg = "Permission Denial: not allowed to send broadcast "
19295                                 + action + " to "
19296                                 + intent.getComponent().getPackageName() + " from "
19297                                 + callerPackage;
19298                         Slog.w(TAG, msg);
19299                         throw new SecurityException(msg);
19300                     }
19301                 } else {
19302                     // Limit broadcast to their own package.
19303                     intent.setPackage(callerPackage);
19304                 }
19305             }
19306         }
19307
19308         if (action != null) {
19309             if (getBackgroundLaunchBroadcasts().contains(action)) {
19310                 if (DEBUG_BACKGROUND_CHECK) {
19311                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19312                 }
19313                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19314             }
19315
19316             switch (action) {
19317                 case Intent.ACTION_UID_REMOVED:
19318                 case Intent.ACTION_PACKAGE_REMOVED:
19319                 case Intent.ACTION_PACKAGE_CHANGED:
19320                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19321                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19322                 case Intent.ACTION_PACKAGES_SUSPENDED:
19323                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19324                     // Handle special intents: if this broadcast is from the package
19325                     // manager about a package being removed, we need to remove all of
19326                     // its activities from the history stack.
19327                     if (checkComponentPermission(
19328                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19329                             callingPid, callingUid, -1, true)
19330                             != PackageManager.PERMISSION_GRANTED) {
19331                         String msg = "Permission Denial: " + intent.getAction()
19332                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19333                                 + ", uid=" + callingUid + ")"
19334                                 + " requires "
19335                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19336                         Slog.w(TAG, msg);
19337                         throw new SecurityException(msg);
19338                     }
19339                     switch (action) {
19340                         case Intent.ACTION_UID_REMOVED:
19341                             final int uid = getUidFromIntent(intent);
19342                             if (uid >= 0) {
19343                                 mBatteryStatsService.removeUid(uid);
19344                                 mAppOpsService.uidRemoved(uid);
19345                             }
19346                             break;
19347                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19348                             // If resources are unavailable just force stop all those packages
19349                             // and flush the attribute cache as well.
19350                             String list[] =
19351                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19352                             if (list != null && list.length > 0) {
19353                                 for (int i = 0; i < list.length; i++) {
19354                                     forceStopPackageLocked(list[i], -1, false, true, true,
19355                                             false, false, userId, "storage unmount");
19356                                 }
19357                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19358                                 sendPackageBroadcastLocked(
19359                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19360                                         list, userId);
19361                             }
19362                             break;
19363                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19364                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19365                             break;
19366                         case Intent.ACTION_PACKAGE_REMOVED:
19367                         case Intent.ACTION_PACKAGE_CHANGED:
19368                             Uri data = intent.getData();
19369                             String ssp;
19370                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19371                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19372                                 final boolean replacing =
19373                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19374                                 final boolean killProcess =
19375                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19376                                 final boolean fullUninstall = removed && !replacing;
19377                                 if (removed) {
19378                                     if (killProcess) {
19379                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19380                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19381                                                 false, true, true, false, fullUninstall, userId,
19382                                                 removed ? "pkg removed" : "pkg changed");
19383                                     }
19384                                     final int cmd = killProcess
19385                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19386                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19387                                     sendPackageBroadcastLocked(cmd,
19388                                             new String[] {ssp}, userId);
19389                                     if (fullUninstall) {
19390                                         mAppOpsService.packageRemoved(
19391                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19392
19393                                         // Remove all permissions granted from/to this package
19394                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19395
19396                                         removeTasksByPackageNameLocked(ssp, userId);
19397
19398                                         mServices.forceStopPackageLocked(ssp, userId);
19399
19400                                         // Hide the "unsupported display" dialog if necessary.
19401                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19402                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19403                                             mUnsupportedDisplaySizeDialog.dismiss();
19404                                             mUnsupportedDisplaySizeDialog = null;
19405                                         }
19406                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19407                                         mBatteryStatsService.notePackageUninstalled(ssp);
19408                                     }
19409                                 } else {
19410                                     if (killProcess) {
19411                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19412                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19413                                                 userId, ProcessList.INVALID_ADJ,
19414                                                 false, true, true, false, "change " + ssp);
19415                                     }
19416                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19417                                             intent.getStringArrayExtra(
19418                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19419                                 }
19420                             }
19421                             break;
19422                         case Intent.ACTION_PACKAGES_SUSPENDED:
19423                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19424                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19425                                     intent.getAction());
19426                             final String[] packageNames = intent.getStringArrayExtra(
19427                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19428                             final int userHandle = intent.getIntExtra(
19429                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19430
19431                             synchronized(ActivityManagerService.this) {
19432                                 mRecentTasks.onPackagesSuspendedChanged(
19433                                         packageNames, suspended, userHandle);
19434                             }
19435                             break;
19436                     }
19437                     break;
19438                 case Intent.ACTION_PACKAGE_REPLACED:
19439                 {
19440                     final Uri data = intent.getData();
19441                     final String ssp;
19442                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19443                         ApplicationInfo aInfo = null;
19444                         try {
19445                             aInfo = AppGlobals.getPackageManager()
19446                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19447                         } catch (RemoteException ignore) {}
19448                         if (aInfo == null) {
19449                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19450                                     + " ssp=" + ssp + " data=" + data);
19451                             return ActivityManager.BROADCAST_SUCCESS;
19452                         }
19453                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19454                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19455                                 new String[] {ssp}, userId);
19456                     }
19457                     break;
19458                 }
19459                 case Intent.ACTION_PACKAGE_ADDED:
19460                 {
19461                     // Special case for adding a package: by default turn on compatibility mode.
19462                     Uri data = intent.getData();
19463                     String ssp;
19464                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19465                         final boolean replacing =
19466                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19467                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19468
19469                         try {
19470                             ApplicationInfo ai = AppGlobals.getPackageManager().
19471                                     getApplicationInfo(ssp, 0, 0);
19472                             mBatteryStatsService.notePackageInstalled(ssp,
19473                                     ai != null ? ai.versionCode : 0);
19474                         } catch (RemoteException e) {
19475                         }
19476                     }
19477                     break;
19478                 }
19479                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19480                 {
19481                     Uri data = intent.getData();
19482                     String ssp;
19483                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19484                         // Hide the "unsupported display" dialog if necessary.
19485                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19486                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19487                             mUnsupportedDisplaySizeDialog.dismiss();
19488                             mUnsupportedDisplaySizeDialog = null;
19489                         }
19490                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19491                     }
19492                     break;
19493                 }
19494                 case Intent.ACTION_TIMEZONE_CHANGED:
19495                     // If this is the time zone changed action, queue up a message that will reset
19496                     // the timezone of all currently running processes. This message will get
19497                     // queued up before the broadcast happens.
19498                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19499                     break;
19500                 case Intent.ACTION_TIME_CHANGED:
19501                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19502                     // the tri-state value it may contain and "unknown".
19503                     // For convenience we re-use the Intent extra values.
19504                     final int NO_EXTRA_VALUE_FOUND = -1;
19505                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19506                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19507                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19508                     // Only send a message if the time preference is available.
19509                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19510                         Message updateTimePreferenceMsg =
19511                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19512                                         timeFormatPreferenceMsgValue, 0);
19513                         mHandler.sendMessage(updateTimePreferenceMsg);
19514                     }
19515                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19516                     synchronized (stats) {
19517                         stats.noteCurrentTimeChangedLocked();
19518                     }
19519                     break;
19520                 case Intent.ACTION_CLEAR_DNS_CACHE:
19521                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19522                     break;
19523                 case Proxy.PROXY_CHANGE_ACTION:
19524                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19525                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19526                     break;
19527                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19528                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19529                     // In N we just turned these off; in O we are turing them back on partly,
19530                     // only for registered receivers.  This will still address the main problem
19531                     // (a spam of apps waking up when a picture is taken putting significant
19532                     // memory pressure on the system at a bad point), while still allowing apps
19533                     // that are already actively running to know about this happening.
19534                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19535                     break;
19536                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19537                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19538                     break;
19539                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19540                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19541                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19542                     Log.w(TAG, "Broadcast " + action
19543                             + " no longer supported. It will not be delivered.");
19544                     return ActivityManager.BROADCAST_SUCCESS;
19545             }
19546
19547             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19548                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19549                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19550                 final int uid = getUidFromIntent(intent);
19551                 if (uid != -1) {
19552                     final UidRecord uidRec = mActiveUids.get(uid);
19553                     if (uidRec != null) {
19554                         uidRec.updateHasInternetPermission();
19555                     }
19556                 }
19557             }
19558         }
19559
19560         // Add to the sticky list if requested.
19561         if (sticky) {
19562             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19563                     callingPid, callingUid)
19564                     != PackageManager.PERMISSION_GRANTED) {
19565                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19566                         + callingPid + ", uid=" + callingUid
19567                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19568                 Slog.w(TAG, msg);
19569                 throw new SecurityException(msg);
19570             }
19571             if (requiredPermissions != null && requiredPermissions.length > 0) {
19572                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19573                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19574                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19575             }
19576             if (intent.getComponent() != null) {
19577                 throw new SecurityException(
19578                         "Sticky broadcasts can't target a specific component");
19579             }
19580             // We use userId directly here, since the "all" target is maintained
19581             // as a separate set of sticky broadcasts.
19582             if (userId != UserHandle.USER_ALL) {
19583                 // But first, if this is not a broadcast to all users, then
19584                 // make sure it doesn't conflict with an existing broadcast to
19585                 // all users.
19586                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19587                         UserHandle.USER_ALL);
19588                 if (stickies != null) {
19589                     ArrayList<Intent> list = stickies.get(intent.getAction());
19590                     if (list != null) {
19591                         int N = list.size();
19592                         int i;
19593                         for (i=0; i<N; i++) {
19594                             if (intent.filterEquals(list.get(i))) {
19595                                 throw new IllegalArgumentException(
19596                                         "Sticky broadcast " + intent + " for user "
19597                                         + userId + " conflicts with existing global broadcast");
19598                             }
19599                         }
19600                     }
19601                 }
19602             }
19603             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19604             if (stickies == null) {
19605                 stickies = new ArrayMap<>();
19606                 mStickyBroadcasts.put(userId, stickies);
19607             }
19608             ArrayList<Intent> list = stickies.get(intent.getAction());
19609             if (list == null) {
19610                 list = new ArrayList<>();
19611                 stickies.put(intent.getAction(), list);
19612             }
19613             final int stickiesCount = list.size();
19614             int i;
19615             for (i = 0; i < stickiesCount; i++) {
19616                 if (intent.filterEquals(list.get(i))) {
19617                     // This sticky already exists, replace it.
19618                     list.set(i, new Intent(intent));
19619                     break;
19620                 }
19621             }
19622             if (i >= stickiesCount) {
19623                 list.add(new Intent(intent));
19624             }
19625         }
19626
19627         int[] users;
19628         if (userId == UserHandle.USER_ALL) {
19629             // Caller wants broadcast to go to all started users.
19630             users = mUserController.getStartedUserArrayLocked();
19631         } else {
19632             // Caller wants broadcast to go to one specific user.
19633             users = new int[] {userId};
19634         }
19635
19636         // Figure out who all will receive this broadcast.
19637         List receivers = null;
19638         List<BroadcastFilter> registeredReceivers = null;
19639         // Need to resolve the intent to interested receivers...
19640         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19641                  == 0) {
19642             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19643         }
19644         if (intent.getComponent() == null) {
19645             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19646                 // Query one target user at a time, excluding shell-restricted users
19647                 for (int i = 0; i < users.length; i++) {
19648                     if (mUserController.hasUserRestriction(
19649                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19650                         continue;
19651                     }
19652                     List<BroadcastFilter> registeredReceiversForUser =
19653                             mReceiverResolver.queryIntent(intent,
19654                                     resolvedType, false /*defaultOnly*/, users[i]);
19655                     if (registeredReceivers == null) {
19656                         registeredReceivers = registeredReceiversForUser;
19657                     } else if (registeredReceiversForUser != null) {
19658                         registeredReceivers.addAll(registeredReceiversForUser);
19659                     }
19660                 }
19661             } else {
19662                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19663                         resolvedType, false /*defaultOnly*/, userId);
19664             }
19665         }
19666
19667         final boolean replacePending =
19668                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19669
19670         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19671                 + " replacePending=" + replacePending);
19672
19673         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19674         if (!ordered && NR > 0) {
19675             // If we are not serializing this broadcast, then send the
19676             // registered receivers separately so they don't wait for the
19677             // components to be launched.
19678             if (isCallerSystem) {
19679                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19680                         isProtectedBroadcast, registeredReceivers);
19681             }
19682             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19683             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19684                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19685                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19686                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19687             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19688             final boolean replaced = replacePending
19689                     && (queue.replaceParallelBroadcastLocked(r) != null);
19690             // Note: We assume resultTo is null for non-ordered broadcasts.
19691             if (!replaced) {
19692                 queue.enqueueParallelBroadcastLocked(r);
19693                 queue.scheduleBroadcastsLocked();
19694             }
19695             registeredReceivers = null;
19696             NR = 0;
19697         }
19698
19699         // Merge into one list.
19700         int ir = 0;
19701         if (receivers != null) {
19702             // A special case for PACKAGE_ADDED: do not allow the package
19703             // being added to see this broadcast.  This prevents them from
19704             // using this as a back door to get run as soon as they are
19705             // installed.  Maybe in the future we want to have a special install
19706             // broadcast or such for apps, but we'd like to deliberately make
19707             // this decision.
19708             String skipPackages[] = null;
19709             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19710                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19711                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19712                 Uri data = intent.getData();
19713                 if (data != null) {
19714                     String pkgName = data.getSchemeSpecificPart();
19715                     if (pkgName != null) {
19716                         skipPackages = new String[] { pkgName };
19717                     }
19718                 }
19719             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19720                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19721             }
19722             if (skipPackages != null && (skipPackages.length > 0)) {
19723                 for (String skipPackage : skipPackages) {
19724                     if (skipPackage != null) {
19725                         int NT = receivers.size();
19726                         for (int it=0; it<NT; it++) {
19727                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19728                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19729                                 receivers.remove(it);
19730                                 it--;
19731                                 NT--;
19732                             }
19733                         }
19734                     }
19735                 }
19736             }
19737
19738             int NT = receivers != null ? receivers.size() : 0;
19739             int it = 0;
19740             ResolveInfo curt = null;
19741             BroadcastFilter curr = null;
19742             while (it < NT && ir < NR) {
19743                 if (curt == null) {
19744                     curt = (ResolveInfo)receivers.get(it);
19745                 }
19746                 if (curr == null) {
19747                     curr = registeredReceivers.get(ir);
19748                 }
19749                 if (curr.getPriority() >= curt.priority) {
19750                     // Insert this broadcast record into the final list.
19751                     receivers.add(it, curr);
19752                     ir++;
19753                     curr = null;
19754                     it++;
19755                     NT++;
19756                 } else {
19757                     // Skip to the next ResolveInfo in the final list.
19758                     it++;
19759                     curt = null;
19760                 }
19761             }
19762         }
19763         while (ir < NR) {
19764             if (receivers == null) {
19765                 receivers = new ArrayList();
19766             }
19767             receivers.add(registeredReceivers.get(ir));
19768             ir++;
19769         }
19770
19771         if (isCallerSystem) {
19772             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19773                     isProtectedBroadcast, receivers);
19774         }
19775
19776         if ((receivers != null && receivers.size() > 0)
19777                 || resultTo != null) {
19778             BroadcastQueue queue = broadcastQueueForIntent(intent);
19779             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19780                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19781                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19782                     resultData, resultExtras, ordered, sticky, false, userId);
19783
19784             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19785                     + ": prev had " + queue.mOrderedBroadcasts.size());
19786             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19787                     "Enqueueing broadcast " + r.intent.getAction());
19788
19789             final BroadcastRecord oldRecord =
19790                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19791             if (oldRecord != null) {
19792                 // Replaced, fire the result-to receiver.
19793                 if (oldRecord.resultTo != null) {
19794                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19795                     try {
19796                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19797                                 oldRecord.intent,
19798                                 Activity.RESULT_CANCELED, null, null,
19799                                 false, false, oldRecord.userId);
19800                     } catch (RemoteException e) {
19801                         Slog.w(TAG, "Failure ["
19802                                 + queue.mQueueName + "] sending broadcast result of "
19803                                 + intent, e);
19804
19805                     }
19806                 }
19807             } else {
19808                 queue.enqueueOrderedBroadcastLocked(r);
19809                 queue.scheduleBroadcastsLocked();
19810             }
19811         } else {
19812             // There was nobody interested in the broadcast, but we still want to record
19813             // that it happened.
19814             if (intent.getComponent() == null && intent.getPackage() == null
19815                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19816                 // This was an implicit broadcast... let's record it for posterity.
19817                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19818             }
19819         }
19820
19821         return ActivityManager.BROADCAST_SUCCESS;
19822     }
19823
19824     /**
19825      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19826      */
19827     private int getUidFromIntent(Intent intent) {
19828         if (intent == null) {
19829             return -1;
19830         }
19831         final Bundle intentExtras = intent.getExtras();
19832         return intent.hasExtra(Intent.EXTRA_UID)
19833                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19834     }
19835
19836     final void rotateBroadcastStatsIfNeededLocked() {
19837         final long now = SystemClock.elapsedRealtime();
19838         if (mCurBroadcastStats == null ||
19839                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19840             mLastBroadcastStats = mCurBroadcastStats;
19841             if (mLastBroadcastStats != null) {
19842                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19843                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19844             }
19845             mCurBroadcastStats = new BroadcastStats();
19846         }
19847     }
19848
19849     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19850             int skipCount, long dispatchTime) {
19851         rotateBroadcastStatsIfNeededLocked();
19852         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19853     }
19854
19855     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19856         rotateBroadcastStatsIfNeededLocked();
19857         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19858     }
19859
19860     final Intent verifyBroadcastLocked(Intent intent) {
19861         // Refuse possible leaked file descriptors
19862         if (intent != null && intent.hasFileDescriptors() == true) {
19863             throw new IllegalArgumentException("File descriptors passed in Intent");
19864         }
19865
19866         int flags = intent.getFlags();
19867
19868         if (!mProcessesReady) {
19869             // if the caller really truly claims to know what they're doing, go
19870             // ahead and allow the broadcast without launching any receivers
19871             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19872                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19873             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19874                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19875                         + " before boot completion");
19876                 throw new IllegalStateException("Cannot broadcast before boot completed");
19877             }
19878         }
19879
19880         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19881             throw new IllegalArgumentException(
19882                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19883         }
19884
19885         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19886             switch (Binder.getCallingUid()) {
19887                 case ROOT_UID:
19888                 case SHELL_UID:
19889                     break;
19890                 default:
19891                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19892                             + Binder.getCallingUid());
19893                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19894                     break;
19895             }
19896         }
19897
19898         return intent;
19899     }
19900
19901     public final int broadcastIntent(IApplicationThread caller,
19902             Intent intent, String resolvedType, IIntentReceiver resultTo,
19903             int resultCode, String resultData, Bundle resultExtras,
19904             String[] requiredPermissions, int appOp, Bundle bOptions,
19905             boolean serialized, boolean sticky, int userId) {
19906         enforceNotIsolatedCaller("broadcastIntent");
19907         synchronized(this) {
19908             intent = verifyBroadcastLocked(intent);
19909
19910             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19911             final int callingPid = Binder.getCallingPid();
19912             final int callingUid = Binder.getCallingUid();
19913             final long origId = Binder.clearCallingIdentity();
19914             int res = broadcastIntentLocked(callerApp,
19915                     callerApp != null ? callerApp.info.packageName : null,
19916                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19917                     requiredPermissions, appOp, bOptions, serialized, sticky,
19918                     callingPid, callingUid, userId);
19919             Binder.restoreCallingIdentity(origId);
19920             return res;
19921         }
19922     }
19923
19924
19925     int broadcastIntentInPackage(String packageName, int uid,
19926             Intent intent, String resolvedType, IIntentReceiver resultTo,
19927             int resultCode, String resultData, Bundle resultExtras,
19928             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19929             int userId) {
19930         synchronized(this) {
19931             intent = verifyBroadcastLocked(intent);
19932
19933             final long origId = Binder.clearCallingIdentity();
19934             String[] requiredPermissions = requiredPermission == null ? null
19935                     : new String[] {requiredPermission};
19936             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19937                     resultTo, resultCode, resultData, resultExtras,
19938                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19939                     sticky, -1, uid, userId);
19940             Binder.restoreCallingIdentity(origId);
19941             return res;
19942         }
19943     }
19944
19945     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19946         // Refuse possible leaked file descriptors
19947         if (intent != null && intent.hasFileDescriptors() == true) {
19948             throw new IllegalArgumentException("File descriptors passed in Intent");
19949         }
19950
19951         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19952                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19953
19954         synchronized(this) {
19955             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19956                     != PackageManager.PERMISSION_GRANTED) {
19957                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19958                         + Binder.getCallingPid()
19959                         + ", uid=" + Binder.getCallingUid()
19960                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19961                 Slog.w(TAG, msg);
19962                 throw new SecurityException(msg);
19963             }
19964             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19965             if (stickies != null) {
19966                 ArrayList<Intent> list = stickies.get(intent.getAction());
19967                 if (list != null) {
19968                     int N = list.size();
19969                     int i;
19970                     for (i=0; i<N; i++) {
19971                         if (intent.filterEquals(list.get(i))) {
19972                             list.remove(i);
19973                             break;
19974                         }
19975                     }
19976                     if (list.size() <= 0) {
19977                         stickies.remove(intent.getAction());
19978                     }
19979                 }
19980                 if (stickies.size() <= 0) {
19981                     mStickyBroadcasts.remove(userId);
19982                 }
19983             }
19984         }
19985     }
19986
19987     void backgroundServicesFinishedLocked(int userId) {
19988         for (BroadcastQueue queue : mBroadcastQueues) {
19989             queue.backgroundServicesFinishedLocked(userId);
19990         }
19991     }
19992
19993     public void finishReceiver(IBinder who, int resultCode, String resultData,
19994             Bundle resultExtras, boolean resultAbort, int flags) {
19995         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19996
19997         // Refuse possible leaked file descriptors
19998         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19999             throw new IllegalArgumentException("File descriptors passed in Bundle");
20000         }
20001
20002         final long origId = Binder.clearCallingIdentity();
20003         try {
20004             boolean doNext = false;
20005             BroadcastRecord r;
20006
20007             synchronized(this) {
20008                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
20009                         ? mFgBroadcastQueue : mBgBroadcastQueue;
20010                 r = queue.getMatchingOrderedReceiver(who);
20011                 if (r != null) {
20012                     doNext = r.queue.finishReceiverLocked(r, resultCode,
20013                         resultData, resultExtras, resultAbort, true);
20014                 }
20015             }
20016
20017             if (doNext) {
20018                 r.queue.processNextBroadcast(false);
20019             }
20020             trimApplications();
20021         } finally {
20022             Binder.restoreCallingIdentity(origId);
20023         }
20024     }
20025
20026     // =========================================================
20027     // INSTRUMENTATION
20028     // =========================================================
20029
20030     public boolean startInstrumentation(ComponentName className,
20031             String profileFile, int flags, Bundle arguments,
20032             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
20033             int userId, String abiOverride) {
20034         enforceNotIsolatedCaller("startInstrumentation");
20035         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20036                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
20037         // Refuse possible leaked file descriptors
20038         if (arguments != null && arguments.hasFileDescriptors()) {
20039             throw new IllegalArgumentException("File descriptors passed in Bundle");
20040         }
20041
20042         synchronized(this) {
20043             InstrumentationInfo ii = null;
20044             ApplicationInfo ai = null;
20045             try {
20046                 ii = mContext.getPackageManager().getInstrumentationInfo(
20047                     className, STOCK_PM_FLAGS);
20048                 ai = AppGlobals.getPackageManager().getApplicationInfo(
20049                         ii.targetPackage, STOCK_PM_FLAGS, userId);
20050             } catch (PackageManager.NameNotFoundException e) {
20051             } catch (RemoteException e) {
20052             }
20053             if (ii == null) {
20054                 reportStartInstrumentationFailureLocked(watcher, className,
20055                         "Unable to find instrumentation info for: " + className);
20056                 return false;
20057             }
20058             if (ai == null) {
20059                 reportStartInstrumentationFailureLocked(watcher, className,
20060                         "Unable to find instrumentation target package: " + ii.targetPackage);
20061                 return false;
20062             }
20063             if (!ai.hasCode()) {
20064                 reportStartInstrumentationFailureLocked(watcher, className,
20065                         "Instrumentation target has no code: " + ii.targetPackage);
20066                 return false;
20067             }
20068
20069             int match = mContext.getPackageManager().checkSignatures(
20070                     ii.targetPackage, ii.packageName);
20071             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20072                 String msg = "Permission Denial: starting instrumentation "
20073                         + className + " from pid="
20074                         + Binder.getCallingPid()
20075                         + ", uid=" + Binder.getCallingPid()
20076                         + " not allowed because package " + ii.packageName
20077                         + " does not have a signature matching the target "
20078                         + ii.targetPackage;
20079                 reportStartInstrumentationFailureLocked(watcher, className, msg);
20080                 throw new SecurityException(msg);
20081             }
20082
20083             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20084             activeInstr.mClass = className;
20085             String defProcess = ai.processName;;
20086             if (ii.targetProcesses == null) {
20087                 activeInstr.mTargetProcesses = new String[]{ai.processName};
20088             } else if (ii.targetProcesses.equals("*")) {
20089                 activeInstr.mTargetProcesses = new String[0];
20090             } else {
20091                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20092                 defProcess = activeInstr.mTargetProcesses[0];
20093             }
20094             activeInstr.mTargetInfo = ai;
20095             activeInstr.mProfileFile = profileFile;
20096             activeInstr.mArguments = arguments;
20097             activeInstr.mWatcher = watcher;
20098             activeInstr.mUiAutomationConnection = uiAutomationConnection;
20099             activeInstr.mResultClass = className;
20100
20101             final long origId = Binder.clearCallingIdentity();
20102             // Instrumentation can kill and relaunch even persistent processes
20103             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20104                     "start instr");
20105             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20106             app.instr = activeInstr;
20107             activeInstr.mFinished = false;
20108             activeInstr.mRunningProcesses.add(app);
20109             if (!mActiveInstrumentation.contains(activeInstr)) {
20110                 mActiveInstrumentation.add(activeInstr);
20111             }
20112             Binder.restoreCallingIdentity(origId);
20113         }
20114
20115         return true;
20116     }
20117
20118     /**
20119      * Report errors that occur while attempting to start Instrumentation.  Always writes the
20120      * error to the logs, but if somebody is watching, send the report there too.  This enables
20121      * the "am" command to report errors with more information.
20122      *
20123      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20124      * @param cn The component name of the instrumentation.
20125      * @param report The error report.
20126      */
20127     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20128             ComponentName cn, String report) {
20129         Slog.w(TAG, report);
20130         if (watcher != null) {
20131             Bundle results = new Bundle();
20132             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20133             results.putString("Error", report);
20134             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20135         }
20136     }
20137
20138     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20139         if (app.instr == null) {
20140             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20141             return;
20142         }
20143
20144         if (!app.instr.mFinished && results != null) {
20145             if (app.instr.mCurResults == null) {
20146                 app.instr.mCurResults = new Bundle(results);
20147             } else {
20148                 app.instr.mCurResults.putAll(results);
20149             }
20150         }
20151     }
20152
20153     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20154         int userId = UserHandle.getCallingUserId();
20155         // Refuse possible leaked file descriptors
20156         if (results != null && results.hasFileDescriptors()) {
20157             throw new IllegalArgumentException("File descriptors passed in Intent");
20158         }
20159
20160         synchronized(this) {
20161             ProcessRecord app = getRecordForAppLocked(target);
20162             if (app == null) {
20163                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20164                 return;
20165             }
20166             final long origId = Binder.clearCallingIdentity();
20167             addInstrumentationResultsLocked(app, results);
20168             Binder.restoreCallingIdentity(origId);
20169         }
20170     }
20171
20172     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20173         if (app.instr == null) {
20174             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20175             return;
20176         }
20177
20178         if (!app.instr.mFinished) {
20179             if (app.instr.mWatcher != null) {
20180                 Bundle finalResults = app.instr.mCurResults;
20181                 if (finalResults != null) {
20182                     if (app.instr.mCurResults != null && results != null) {
20183                         finalResults.putAll(results);
20184                     }
20185                 } else {
20186                     finalResults = results;
20187                 }
20188                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20189                         app.instr.mClass, resultCode, finalResults);
20190             }
20191
20192             // Can't call out of the system process with a lock held, so post a message.
20193             if (app.instr.mUiAutomationConnection != null) {
20194                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20195                         app.instr.mUiAutomationConnection).sendToTarget();
20196             }
20197             app.instr.mFinished = true;
20198         }
20199
20200         app.instr.removeProcess(app);
20201         app.instr = null;
20202
20203         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20204                 "finished inst");
20205     }
20206
20207     public void finishInstrumentation(IApplicationThread target,
20208             int resultCode, Bundle results) {
20209         int userId = UserHandle.getCallingUserId();
20210         // Refuse possible leaked file descriptors
20211         if (results != null && results.hasFileDescriptors()) {
20212             throw new IllegalArgumentException("File descriptors passed in Intent");
20213         }
20214
20215         synchronized(this) {
20216             ProcessRecord app = getRecordForAppLocked(target);
20217             if (app == null) {
20218                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20219                 return;
20220             }
20221             final long origId = Binder.clearCallingIdentity();
20222             finishInstrumentationLocked(app, resultCode, results);
20223             Binder.restoreCallingIdentity(origId);
20224         }
20225     }
20226
20227     // =========================================================
20228     // CONFIGURATION
20229     // =========================================================
20230
20231     public ConfigurationInfo getDeviceConfigurationInfo() {
20232         ConfigurationInfo config = new ConfigurationInfo();
20233         synchronized (this) {
20234             final Configuration globalConfig = getGlobalConfiguration();
20235             config.reqTouchScreen = globalConfig.touchscreen;
20236             config.reqKeyboardType = globalConfig.keyboard;
20237             config.reqNavigation = globalConfig.navigation;
20238             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20239                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20240                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20241             }
20242             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20243                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20244                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20245             }
20246             config.reqGlEsVersion = GL_ES_VERSION;
20247         }
20248         return config;
20249     }
20250
20251     ActivityStack getFocusedStack() {
20252         return mStackSupervisor.getFocusedStack();
20253     }
20254
20255     @Override
20256     public int getFocusedStackId() throws RemoteException {
20257         ActivityStack focusedStack = getFocusedStack();
20258         if (focusedStack != null) {
20259             return focusedStack.getStackId();
20260         }
20261         return -1;
20262     }
20263
20264     public Configuration getConfiguration() {
20265         Configuration ci;
20266         synchronized(this) {
20267             ci = new Configuration(getGlobalConfiguration());
20268             ci.userSetLocale = false;
20269         }
20270         return ci;
20271     }
20272
20273     @Override
20274     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20275         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20276         synchronized (this) {
20277             mSuppressResizeConfigChanges = suppress;
20278         }
20279     }
20280
20281     /**
20282      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20283      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20284      *       activity and clearing the task at the same time.
20285      */
20286     @Override
20287     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20288         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20289         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20290             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20291         }
20292         synchronized (this) {
20293             final long origId = Binder.clearCallingIdentity();
20294             try {
20295                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20296             } finally {
20297                 Binder.restoreCallingIdentity(origId);
20298             }
20299         }
20300     }
20301
20302     @Override
20303     public void updatePersistentConfiguration(Configuration values) {
20304         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20305         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20306         if (values == null) {
20307             throw new NullPointerException("Configuration must not be null");
20308         }
20309
20310         int userId = UserHandle.getCallingUserId();
20311
20312         synchronized(this) {
20313             updatePersistentConfigurationLocked(values, userId);
20314         }
20315     }
20316
20317     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20318         final long origId = Binder.clearCallingIdentity();
20319         try {
20320             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20321         } finally {
20322             Binder.restoreCallingIdentity(origId);
20323         }
20324     }
20325
20326     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20327         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20328                 FONT_SCALE, 1.0f, userId);
20329
20330         synchronized (this) {
20331             if (getGlobalConfiguration().fontScale == scaleFactor) {
20332                 return;
20333             }
20334
20335             final Configuration configuration
20336                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20337             configuration.fontScale = scaleFactor;
20338             updatePersistentConfigurationLocked(configuration, userId);
20339         }
20340     }
20341
20342     private void enforceWriteSettingsPermission(String func) {
20343         int uid = Binder.getCallingUid();
20344         if (uid == ROOT_UID) {
20345             return;
20346         }
20347
20348         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20349                 Settings.getPackageNameForUid(mContext, uid), false)) {
20350             return;
20351         }
20352
20353         String msg = "Permission Denial: " + func + " from pid="
20354                 + Binder.getCallingPid()
20355                 + ", uid=" + uid
20356                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20357         Slog.w(TAG, msg);
20358         throw new SecurityException(msg);
20359     }
20360
20361     @Override
20362     public boolean updateConfiguration(Configuration values) {
20363         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20364
20365         synchronized(this) {
20366             if (values == null && mWindowManager != null) {
20367                 // sentinel: fetch the current configuration from the window manager
20368                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20369             }
20370
20371             if (mWindowManager != null) {
20372                 // Update OOM levels based on display size.
20373                 mProcessList.applyDisplaySize(mWindowManager);
20374             }
20375
20376             final long origId = Binder.clearCallingIdentity();
20377             try {
20378                 if (values != null) {
20379                     Settings.System.clearConfiguration(values);
20380                 }
20381                 updateConfigurationLocked(values, null, false, false /* persistent */,
20382                         UserHandle.USER_NULL, false /* deferResume */,
20383                         mTmpUpdateConfigurationResult);
20384                 return mTmpUpdateConfigurationResult.changes != 0;
20385             } finally {
20386                 Binder.restoreCallingIdentity(origId);
20387             }
20388         }
20389     }
20390
20391     void updateUserConfigurationLocked() {
20392         final Configuration configuration = new Configuration(getGlobalConfiguration());
20393         final int currentUserId = mUserController.getCurrentUserIdLocked();
20394         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20395                 currentUserId, Settings.System.canWrite(mContext));
20396         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20397                 false /* persistent */, currentUserId, false /* deferResume */);
20398     }
20399
20400     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20401             boolean initLocale) {
20402         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20403     }
20404
20405     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20406             boolean initLocale, boolean deferResume) {
20407         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20408         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20409                 UserHandle.USER_NULL, deferResume);
20410     }
20411
20412     // To cache the list of supported system locales
20413     private String[] mSupportedSystemLocales = null;
20414
20415     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20416             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20417         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20418                 deferResume, null /* result */);
20419     }
20420
20421     /**
20422      * Do either or both things: (1) change the current configuration, and (2)
20423      * make sure the given activity is running with the (now) current
20424      * configuration.  Returns true if the activity has been left running, or
20425      * false if <var>starting</var> is being destroyed to match the new
20426      * configuration.
20427      *
20428      * @param userId is only used when persistent parameter is set to true to persist configuration
20429      *               for that particular user
20430      */
20431     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20432             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20433             UpdateConfigurationResult result) {
20434         int changes = 0;
20435         boolean kept = true;
20436
20437         if (mWindowManager != null) {
20438             mWindowManager.deferSurfaceLayout();
20439         }
20440         try {
20441             if (values != null) {
20442                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20443                         deferResume);
20444             }
20445
20446             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20447         } finally {
20448             if (mWindowManager != null) {
20449                 mWindowManager.continueSurfaceLayout();
20450             }
20451         }
20452
20453         if (result != null) {
20454             result.changes = changes;
20455             result.activityRelaunched = !kept;
20456         }
20457         return kept;
20458     }
20459
20460     /** Update default (global) configuration and notify listeners about changes. */
20461     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20462             boolean persistent, int userId, boolean deferResume) {
20463         mTempConfig.setTo(getGlobalConfiguration());
20464         final int changes = mTempConfig.updateFrom(values);
20465         if (changes == 0) {
20466             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20467             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20468             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20469             // (even if there are no actual changes) to unfreeze the window.
20470             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20471             return 0;
20472         }
20473
20474         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20475                 "Updating global configuration to: " + values);
20476
20477         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20478
20479         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20480             final LocaleList locales = values.getLocales();
20481             int bestLocaleIndex = 0;
20482             if (locales.size() > 1) {
20483                 if (mSupportedSystemLocales == null) {
20484                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20485                 }
20486                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20487             }
20488             SystemProperties.set("persist.sys.locale",
20489                     locales.get(bestLocaleIndex).toLanguageTag());
20490             LocaleList.setDefault(locales, bestLocaleIndex);
20491             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20492                     locales.get(bestLocaleIndex)));
20493         }
20494
20495         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20496         mTempConfig.seq = mConfigurationSeq;
20497
20498         // Update stored global config and notify everyone about the change.
20499         mStackSupervisor.onConfigurationChanged(mTempConfig);
20500
20501         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20502         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20503         mUsageStatsService.reportConfigurationChange(mTempConfig,
20504                 mUserController.getCurrentUserIdLocked());
20505
20506         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20507         mShowDialogs = shouldShowDialogs(mTempConfig);
20508
20509         AttributeCache ac = AttributeCache.instance();
20510         if (ac != null) {
20511             ac.updateConfiguration(mTempConfig);
20512         }
20513
20514         // Make sure all resources in our process are updated right now, so that anyone who is going
20515         // to retrieve resource values after we return will be sure to get the new ones. This is
20516         // especially important during boot, where the first config change needs to guarantee all
20517         // resources have that config before following boot code is executed.
20518         mSystemThread.applyConfigurationToResources(mTempConfig);
20519
20520         // We need another copy of global config because we're scheduling some calls instead of
20521         // running them in place. We need to be sure that object we send will be handled unchanged.
20522         final Configuration configCopy = new Configuration(mTempConfig);
20523         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20524             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20525             msg.obj = configCopy;
20526             msg.arg1 = userId;
20527             mHandler.sendMessage(msg);
20528         }
20529
20530         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20531             ProcessRecord app = mLruProcesses.get(i);
20532             try {
20533                 if (app.thread != null) {
20534                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20535                             + app.processName + " new config " + configCopy);
20536                     app.thread.scheduleConfigurationChanged(configCopy);
20537                 }
20538             } catch (Exception e) {
20539             }
20540         }
20541
20542         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20543         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20544                 | Intent.FLAG_RECEIVER_FOREGROUND
20545                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20546         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20547                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20548                 UserHandle.USER_ALL);
20549         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20550             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20551             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20552                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20553                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20554             if (initLocale || !mProcessesReady) {
20555                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20556             }
20557             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20558                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20559                     UserHandle.USER_ALL);
20560         }
20561
20562         // Override configuration of the default display duplicates global config, so we need to
20563         // update it also. This will also notify WindowManager about changes.
20564         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20565                 DEFAULT_DISPLAY);
20566
20567         return changes;
20568     }
20569
20570     @Override
20571     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20572         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20573
20574         synchronized (this) {
20575             // Check if display is initialized in AM.
20576             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20577                 // Call might come when display is not yet added or has already been removed.
20578                 if (DEBUG_CONFIGURATION) {
20579                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20580                             + displayId);
20581                 }
20582                 return false;
20583             }
20584
20585             if (values == null && mWindowManager != null) {
20586                 // sentinel: fetch the current configuration from the window manager
20587                 values = mWindowManager.computeNewConfiguration(displayId);
20588             }
20589
20590             if (mWindowManager != null) {
20591                 // Update OOM levels based on display size.
20592                 mProcessList.applyDisplaySize(mWindowManager);
20593             }
20594
20595             final long origId = Binder.clearCallingIdentity();
20596             try {
20597                 if (values != null) {
20598                     Settings.System.clearConfiguration(values);
20599                 }
20600                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20601                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20602                 return mTmpUpdateConfigurationResult.changes != 0;
20603             } finally {
20604                 Binder.restoreCallingIdentity(origId);
20605             }
20606         }
20607     }
20608
20609     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20610             boolean deferResume, int displayId) {
20611         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20612                 displayId, null /* result */);
20613     }
20614
20615     /**
20616      * Updates override configuration specific for the selected display. If no config is provided,
20617      * new one will be computed in WM based on current display info.
20618      */
20619     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20620             ActivityRecord starting, boolean deferResume, int displayId,
20621             UpdateConfigurationResult result) {
20622         int changes = 0;
20623         boolean kept = true;
20624
20625         if (mWindowManager != null) {
20626             mWindowManager.deferSurfaceLayout();
20627         }
20628         try {
20629             if (values != null) {
20630                 if (displayId == DEFAULT_DISPLAY) {
20631                     // Override configuration of the default display duplicates global config, so
20632                     // we're calling global config update instead for default display. It will also
20633                     // apply the correct override config.
20634                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20635                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20636                 } else {
20637                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20638                 }
20639             }
20640
20641             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20642         } finally {
20643             if (mWindowManager != null) {
20644                 mWindowManager.continueSurfaceLayout();
20645             }
20646         }
20647
20648         if (result != null) {
20649             result.changes = changes;
20650             result.activityRelaunched = !kept;
20651         }
20652         return kept;
20653     }
20654
20655     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20656             int displayId) {
20657         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20658         final int changes = mTempConfig.updateFrom(values);
20659         if (changes != 0) {
20660             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20661                     + mTempConfig + " for displayId=" + displayId);
20662             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20663
20664             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20665             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20666                 // Reset the unsupported display size dialog.
20667                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20668
20669                 killAllBackgroundProcessesExcept(N,
20670                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20671             }
20672         }
20673
20674         // Update the configuration with WM first and check if any of the stacks need to be resized
20675         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20676         // necessary. This way we don't need to relaunch again afterwards in
20677         // ensureActivityConfigurationLocked().
20678         if (mWindowManager != null) {
20679             final int[] resizedStacks =
20680                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20681             if (resizedStacks != null) {
20682                 for (int stackId : resizedStacks) {
20683                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20684                 }
20685             }
20686         }
20687
20688         return changes;
20689     }
20690
20691     /** Applies latest configuration and/or visibility updates if needed. */
20692     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20693         boolean kept = true;
20694         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20695         // mainStack is null during startup.
20696         if (mainStack != null) {
20697             if (changes != 0 && starting == null) {
20698                 // If the configuration changed, and the caller is not already
20699                 // in the process of starting an activity, then find the top
20700                 // activity to check if its configuration needs to change.
20701                 starting = mainStack.topRunningActivityLocked();
20702             }
20703
20704             if (starting != null) {
20705                 kept = starting.ensureActivityConfigurationLocked(changes,
20706                         false /* preserveWindow */);
20707                 // And we need to make sure at this point that all other activities
20708                 // are made visible with the correct configuration.
20709                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20710                         !PRESERVE_WINDOWS);
20711             }
20712         }
20713
20714         return kept;
20715     }
20716
20717     /** Helper method that requests bounds from WM and applies them to stack. */
20718     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20719         final Rect newStackBounds = new Rect();
20720         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20721         mStackSupervisor.resizeStackLocked(
20722                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20723                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20724                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20725     }
20726
20727     /**
20728      * Decide based on the configuration whether we should show the ANR,
20729      * crash, etc dialogs.  The idea is that if there is no affordance to
20730      * press the on-screen buttons, or the user experience would be more
20731      * greatly impacted than the crash itself, we shouldn't show the dialog.
20732      *
20733      * A thought: SystemUI might also want to get told about this, the Power
20734      * dialog / global actions also might want different behaviors.
20735      */
20736     private static boolean shouldShowDialogs(Configuration config) {
20737         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20738                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20739                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20740         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20741         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20742                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20743                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20744                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20745         return inputMethodExists && uiModeSupportsDialogs;
20746     }
20747
20748     @Override
20749     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20750         synchronized (this) {
20751             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20752             if (srec != null) {
20753                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20754             }
20755         }
20756         return false;
20757     }
20758
20759     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20760             Intent resultData) {
20761
20762         synchronized (this) {
20763             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20764             if (r != null) {
20765                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20766             }
20767             return false;
20768         }
20769     }
20770
20771     public int getLaunchedFromUid(IBinder activityToken) {
20772         ActivityRecord srec;
20773         synchronized (this) {
20774             srec = ActivityRecord.forTokenLocked(activityToken);
20775         }
20776         if (srec == null) {
20777             return -1;
20778         }
20779         return srec.launchedFromUid;
20780     }
20781
20782     public String getLaunchedFromPackage(IBinder activityToken) {
20783         ActivityRecord srec;
20784         synchronized (this) {
20785             srec = ActivityRecord.forTokenLocked(activityToken);
20786         }
20787         if (srec == null) {
20788             return null;
20789         }
20790         return srec.launchedFromPackage;
20791     }
20792
20793     // =========================================================
20794     // LIFETIME MANAGEMENT
20795     // =========================================================
20796
20797     // Returns whether the app is receiving broadcast.
20798     // If receiving, fetch all broadcast queues which the app is
20799     // the current [or imminent] receiver on.
20800     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20801             ArraySet<BroadcastQueue> receivingQueues) {
20802         if (!app.curReceivers.isEmpty()) {
20803             for (BroadcastRecord r : app.curReceivers) {
20804                 receivingQueues.add(r.queue);
20805             }
20806             return true;
20807         }
20808
20809         // It's not the current receiver, but it might be starting up to become one
20810         for (BroadcastQueue queue : mBroadcastQueues) {
20811             final BroadcastRecord r = queue.mPendingBroadcast;
20812             if (r != null && r.curApp == app) {
20813                 // found it; report which queue it's in
20814                 receivingQueues.add(queue);
20815             }
20816         }
20817
20818         return !receivingQueues.isEmpty();
20819     }
20820
20821     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20822             int targetUid, ComponentName targetComponent, String targetProcess) {
20823         if (!mTrackingAssociations) {
20824             return null;
20825         }
20826         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20827                 = mAssociations.get(targetUid);
20828         if (components == null) {
20829             components = new ArrayMap<>();
20830             mAssociations.put(targetUid, components);
20831         }
20832         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20833         if (sourceUids == null) {
20834             sourceUids = new SparseArray<>();
20835             components.put(targetComponent, sourceUids);
20836         }
20837         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20838         if (sourceProcesses == null) {
20839             sourceProcesses = new ArrayMap<>();
20840             sourceUids.put(sourceUid, sourceProcesses);
20841         }
20842         Association ass = sourceProcesses.get(sourceProcess);
20843         if (ass == null) {
20844             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20845                     targetProcess);
20846             sourceProcesses.put(sourceProcess, ass);
20847         }
20848         ass.mCount++;
20849         ass.mNesting++;
20850         if (ass.mNesting == 1) {
20851             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20852             ass.mLastState = sourceState;
20853         }
20854         return ass;
20855     }
20856
20857     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20858             ComponentName targetComponent) {
20859         if (!mTrackingAssociations) {
20860             return;
20861         }
20862         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20863                 = mAssociations.get(targetUid);
20864         if (components == null) {
20865             return;
20866         }
20867         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20868         if (sourceUids == null) {
20869             return;
20870         }
20871         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20872         if (sourceProcesses == null) {
20873             return;
20874         }
20875         Association ass = sourceProcesses.get(sourceProcess);
20876         if (ass == null || ass.mNesting <= 0) {
20877             return;
20878         }
20879         ass.mNesting--;
20880         if (ass.mNesting == 0) {
20881             long uptime = SystemClock.uptimeMillis();
20882             ass.mTime += uptime - ass.mStartTime;
20883             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20884                     += uptime - ass.mLastStateUptime;
20885             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20886         }
20887     }
20888
20889     private void noteUidProcessState(final int uid, final int state) {
20890         mBatteryStatsService.noteUidProcessState(uid, state);
20891         if (mTrackingAssociations) {
20892             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20893                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20894                         = mAssociations.valueAt(i1);
20895                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20896                     SparseArray<ArrayMap<String, Association>> sourceUids
20897                             = targetComponents.valueAt(i2);
20898                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20899                     if (sourceProcesses != null) {
20900                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20901                             Association ass = sourceProcesses.valueAt(i4);
20902                             if (ass.mNesting >= 1) {
20903                                 // currently associated
20904                                 long uptime = SystemClock.uptimeMillis();
20905                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20906                                         += uptime - ass.mLastStateUptime;
20907                                 ass.mLastState = state;
20908                                 ass.mLastStateUptime = uptime;
20909                             }
20910                         }
20911                     }
20912                 }
20913             }
20914         }
20915     }
20916
20917     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20918             boolean doingAll, long now) {
20919         if (mAdjSeq == app.adjSeq) {
20920             // This adjustment has already been computed.
20921             return app.curRawAdj;
20922         }
20923
20924         if (app.thread == null) {
20925             app.adjSeq = mAdjSeq;
20926             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20927             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20928             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20929         }
20930
20931         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20932         app.adjSource = null;
20933         app.adjTarget = null;
20934         app.empty = false;
20935         app.cached = false;
20936
20937         final int activitiesSize = app.activities.size();
20938
20939         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20940             // The max adjustment doesn't allow this app to be anything
20941             // below foreground, so it is not worth doing work for it.
20942             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20943             app.adjType = "fixed";
20944             app.adjSeq = mAdjSeq;
20945             app.curRawAdj = app.maxAdj;
20946             app.foregroundActivities = false;
20947             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20948             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20949             // System processes can do UI, and when they do we want to have
20950             // them trim their memory after the user leaves the UI.  To
20951             // facilitate this, here we need to determine whether or not it
20952             // is currently showing UI.
20953             app.systemNoUi = true;
20954             if (app == TOP_APP) {
20955                 app.systemNoUi = false;
20956                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20957                 app.adjType = "pers-top-activity";
20958             } else if (app.hasTopUi) {
20959                 app.systemNoUi = false;
20960                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20961                 app.adjType = "pers-top-ui";
20962             } else if (activitiesSize > 0) {
20963                 for (int j = 0; j < activitiesSize; j++) {
20964                     final ActivityRecord r = app.activities.get(j);
20965                     if (r.visible) {
20966                         app.systemNoUi = false;
20967                     }
20968                 }
20969             }
20970             if (!app.systemNoUi) {
20971                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20972             }
20973             return (app.curAdj=app.maxAdj);
20974         }
20975
20976         app.systemNoUi = false;
20977
20978         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20979
20980         // Determine the importance of the process, starting with most
20981         // important to least, and assign an appropriate OOM adjustment.
20982         int adj;
20983         int schedGroup;
20984         int procState;
20985         boolean foregroundActivities = false;
20986         mTmpBroadcastQueue.clear();
20987         if (app == TOP_APP) {
20988             // The last app on the list is the foreground app.
20989             adj = ProcessList.FOREGROUND_APP_ADJ;
20990             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20991             app.adjType = "top-activity";
20992             foregroundActivities = true;
20993             procState = PROCESS_STATE_CUR_TOP;
20994             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20995         } else if (app.instr != null) {
20996             // Don't want to kill running instrumentation.
20997             adj = ProcessList.FOREGROUND_APP_ADJ;
20998             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20999             app.adjType = "instrumentation";
21000             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21001             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
21002         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
21003             // An app that is currently receiving a broadcast also
21004             // counts as being in the foreground for OOM killer purposes.
21005             // It's placed in a sched group based on the nature of the
21006             // broadcast as reflected by which queue it's active in.
21007             adj = ProcessList.FOREGROUND_APP_ADJ;
21008             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
21009                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
21010             app.adjType = "broadcast";
21011             procState = ActivityManager.PROCESS_STATE_RECEIVER;
21012             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
21013         } else if (app.executingServices.size() > 0) {
21014             // An app that is currently executing a service callback also
21015             // counts as being in the foreground.
21016             adj = ProcessList.FOREGROUND_APP_ADJ;
21017             schedGroup = app.execServicesFg ?
21018                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
21019             app.adjType = "exec-service";
21020             procState = ActivityManager.PROCESS_STATE_SERVICE;
21021             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
21022             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
21023         } else {
21024             // As far as we know the process is empty.  We may change our mind later.
21025             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21026             // At this point we don't actually know the adjustment.  Use the cached adj
21027             // value that the caller wants us to.
21028             adj = cachedAdj;
21029             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21030             app.cached = true;
21031             app.empty = true;
21032             app.adjType = "cch-empty";
21033             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
21034         }
21035
21036         // Examine all activities if not already foreground.
21037         if (!foregroundActivities && activitiesSize > 0) {
21038             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
21039             for (int j = 0; j < activitiesSize; j++) {
21040                 final ActivityRecord r = app.activities.get(j);
21041                 if (r.app != app) {
21042                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
21043                             + " instead of expected " + app);
21044                     if (r.app == null || (r.app.uid == app.uid)) {
21045                         // Only fix things up when they look sane
21046                         r.app = app;
21047                     } else {
21048                         continue;
21049                     }
21050                 }
21051                 if (r.visible) {
21052                     // App has a visible activity; only upgrade adjustment.
21053                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21054                         adj = ProcessList.VISIBLE_APP_ADJ;
21055                         app.adjType = "vis-activity";
21056                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21057                     }
21058                     if (procState > PROCESS_STATE_CUR_TOP) {
21059                         procState = PROCESS_STATE_CUR_TOP;
21060                         app.adjType = "vis-activity";
21061                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21062                     }
21063                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21064                     app.cached = false;
21065                     app.empty = false;
21066                     foregroundActivities = true;
21067                     final TaskRecord task = r.getTask();
21068                     if (task != null && minLayer > 0) {
21069                         final int layer = task.mLayerRank;
21070                         if (layer >= 0 && minLayer > layer) {
21071                             minLayer = layer;
21072                         }
21073                     }
21074                     break;
21075                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21076                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21077                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21078                         app.adjType = "pause-activity";
21079                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21080                     }
21081                     if (procState > PROCESS_STATE_CUR_TOP) {
21082                         procState = PROCESS_STATE_CUR_TOP;
21083                         app.adjType = "pause-activity";
21084                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21085                     }
21086                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21087                     app.cached = false;
21088                     app.empty = false;
21089                     foregroundActivities = true;
21090                 } else if (r.state == ActivityState.STOPPING) {
21091                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21092                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21093                         app.adjType = "stop-activity";
21094                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21095                     }
21096                     // For the process state, we will at this point consider the
21097                     // process to be cached.  It will be cached either as an activity
21098                     // or empty depending on whether the activity is finishing.  We do
21099                     // this so that we can treat the process as cached for purposes of
21100                     // memory trimming (determing current memory level, trim command to
21101                     // send to process) since there can be an arbitrary number of stopping
21102                     // processes and they should soon all go into the cached state.
21103                     if (!r.finishing) {
21104                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21105                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21106                             app.adjType = "stop-activity";
21107                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21108                         }
21109                     }
21110                     app.cached = false;
21111                     app.empty = false;
21112                     foregroundActivities = true;
21113                 } else {
21114                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21115                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21116                         app.adjType = "cch-act";
21117                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21118                     }
21119                 }
21120             }
21121             if (adj == ProcessList.VISIBLE_APP_ADJ) {
21122                 adj += minLayer;
21123             }
21124         }
21125
21126         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21127                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21128             if (app.foregroundServices) {
21129                 // The user is aware of this app, so make it visible.
21130                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21131                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21132                 app.cached = false;
21133                 app.adjType = "fg-service";
21134                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21135                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21136             } else if (app.hasOverlayUi) {
21137                 // The process is display an overlay UI.
21138                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21139                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21140                 app.cached = false;
21141                 app.adjType = "has-overlay-ui";
21142                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21143                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21144             }
21145         }
21146
21147         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21148                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21149             if (app.forcingToImportant != null) {
21150                 // This is currently used for toasts...  they are not interactive, and
21151                 // we don't want them to cause the app to become fully foreground (and
21152                 // thus out of background check), so we yes the best background level we can.
21153                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21154                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21155                 app.cached = false;
21156                 app.adjType = "force-imp";
21157                 app.adjSource = app.forcingToImportant;
21158                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21159                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21160             }
21161         }
21162
21163         if (app == mHeavyWeightProcess) {
21164             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21165                 // We don't want to kill the current heavy-weight process.
21166                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21167                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21168                 app.cached = false;
21169                 app.adjType = "heavy";
21170                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21171             }
21172             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21173                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21174                 app.adjType = "heavy";
21175                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21176             }
21177         }
21178
21179         if (app == mHomeProcess) {
21180             if (adj > ProcessList.HOME_APP_ADJ) {
21181                 // This process is hosting what we currently consider to be the
21182                 // home app, so we don't want to let it go into the background.
21183                 adj = ProcessList.HOME_APP_ADJ;
21184                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21185                 app.cached = false;
21186                 app.adjType = "home";
21187                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21188             }
21189             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21190                 procState = ActivityManager.PROCESS_STATE_HOME;
21191                 app.adjType = "home";
21192                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21193             }
21194         }
21195
21196         if (app == mPreviousProcess && app.activities.size() > 0) {
21197             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21198                 // This was the previous process that showed UI to the user.
21199                 // We want to try to keep it around more aggressively, to give
21200                 // a good experience around switching between two apps.
21201                 adj = ProcessList.PREVIOUS_APP_ADJ;
21202                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21203                 app.cached = false;
21204                 app.adjType = "previous";
21205                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21206             }
21207             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21208                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21209                 app.adjType = "previous";
21210                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21211             }
21212         }
21213
21214         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21215                 + " reason=" + app.adjType);
21216
21217         // By default, we use the computed adjustment.  It may be changed if
21218         // there are applications dependent on our services or providers, but
21219         // this gives us a baseline and makes sure we don't get into an
21220         // infinite recursion.
21221         app.adjSeq = mAdjSeq;
21222         app.curRawAdj = adj;
21223         app.hasStartedServices = false;
21224
21225         if (mBackupTarget != null && app == mBackupTarget.app) {
21226             // If possible we want to avoid killing apps while they're being backed up
21227             if (adj > ProcessList.BACKUP_APP_ADJ) {
21228                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21229                 adj = ProcessList.BACKUP_APP_ADJ;
21230                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21231                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21232                 }
21233                 app.adjType = "backup";
21234                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21235                 app.cached = false;
21236             }
21237             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21238                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21239                 app.adjType = "backup";
21240                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21241             }
21242         }
21243
21244         boolean mayBeTop = false;
21245         String mayBeTopType = null;
21246         Object mayBeTopSource = null;
21247         Object mayBeTopTarget = null;
21248
21249         for (int is = app.services.size()-1;
21250                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21251                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21252                         || procState > ActivityManager.PROCESS_STATE_TOP);
21253                 is--) {
21254             ServiceRecord s = app.services.valueAt(is);
21255             if (s.startRequested) {
21256                 app.hasStartedServices = true;
21257                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21258                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21259                     app.adjType = "started-services";
21260                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21261                 }
21262                 if (app.hasShownUi && app != mHomeProcess) {
21263                     // If this process has shown some UI, let it immediately
21264                     // go to the LRU list because it may be pretty heavy with
21265                     // UI stuff.  We'll tag it with a label just to help
21266                     // debug and understand what is going on.
21267                     if (adj > ProcessList.SERVICE_ADJ) {
21268                         app.adjType = "cch-started-ui-services";
21269                     }
21270                 } else {
21271                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21272                         // This service has seen some activity within
21273                         // recent memory, so we will keep its process ahead
21274                         // of the background processes.
21275                         if (adj > ProcessList.SERVICE_ADJ) {
21276                             adj = ProcessList.SERVICE_ADJ;
21277                             app.adjType = "started-services";
21278                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21279                             app.cached = false;
21280                         }
21281                     }
21282                     // If we have let the service slide into the background
21283                     // state, still have some text describing what it is doing
21284                     // even though the service no longer has an impact.
21285                     if (adj > ProcessList.SERVICE_ADJ) {
21286                         app.adjType = "cch-started-services";
21287                     }
21288                 }
21289             }
21290
21291             for (int conni = s.connections.size()-1;
21292                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21293                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21294                             || procState > ActivityManager.PROCESS_STATE_TOP);
21295                     conni--) {
21296                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21297                 for (int i = 0;
21298                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21299                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21300                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21301                         i++) {
21302                     // XXX should compute this based on the max of
21303                     // all connected clients.
21304                     ConnectionRecord cr = clist.get(i);
21305                     if (cr.binding.client == app) {
21306                         // Binding to ourself is not interesting.
21307                         continue;
21308                     }
21309
21310                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21311                         ProcessRecord client = cr.binding.client;
21312                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21313                                 TOP_APP, doingAll, now);
21314                         int clientProcState = client.curProcState;
21315                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21316                             // If the other app is cached for any reason, for purposes here
21317                             // we are going to consider it empty.  The specific cached state
21318                             // doesn't propagate except under certain conditions.
21319                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21320                         }
21321                         String adjType = null;
21322                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21323                             // Not doing bind OOM management, so treat
21324                             // this guy more like a started service.
21325                             if (app.hasShownUi && app != mHomeProcess) {
21326                                 // If this process has shown some UI, let it immediately
21327                                 // go to the LRU list because it may be pretty heavy with
21328                                 // UI stuff.  We'll tag it with a label just to help
21329                                 // debug and understand what is going on.
21330                                 if (adj > clientAdj) {
21331                                     adjType = "cch-bound-ui-services";
21332                                 }
21333                                 app.cached = false;
21334                                 clientAdj = adj;
21335                                 clientProcState = procState;
21336                             } else {
21337                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21338                                     // This service has not seen activity within
21339                                     // recent memory, so allow it to drop to the
21340                                     // LRU list if there is no other reason to keep
21341                                     // it around.  We'll also tag it with a label just
21342                                     // to help debug and undertand what is going on.
21343                                     if (adj > clientAdj) {
21344                                         adjType = "cch-bound-services";
21345                                     }
21346                                     clientAdj = adj;
21347                                 }
21348                             }
21349                         }
21350                         if (adj > clientAdj) {
21351                             // If this process has recently shown UI, and
21352                             // the process that is binding to it is less
21353                             // important than being visible, then we don't
21354                             // care about the binding as much as we care
21355                             // about letting this process get into the LRU
21356                             // list to be killed and restarted if needed for
21357                             // memory.
21358                             if (app.hasShownUi && app != mHomeProcess
21359                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21360                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21361                                     adjType = "cch-bound-ui-services";
21362                                 }
21363                             } else {
21364                                 int newAdj;
21365                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21366                                         |Context.BIND_IMPORTANT)) != 0) {
21367                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21368                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21369                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21370                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21371                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21372                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21373                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21374                                     newAdj = clientAdj;
21375                                 } else {
21376                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21377                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21378                                     } else {
21379                                         newAdj = adj;
21380                                     }
21381                                 }
21382                                 if (!client.cached) {
21383                                     app.cached = false;
21384                                 }
21385                                 if (adj >  newAdj) {
21386                                     adj = newAdj;
21387                                     adjType = "service";
21388                                 }
21389                             }
21390                         }
21391                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21392                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21393                             // This will treat important bound services identically to
21394                             // the top app, which may behave differently than generic
21395                             // foreground work.
21396                             if (client.curSchedGroup > schedGroup) {
21397                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21398                                     schedGroup = client.curSchedGroup;
21399                                 } else {
21400                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21401                                 }
21402                             }
21403                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21404                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21405                                     // Special handling of clients who are in the top state.
21406                                     // We *may* want to consider this process to be in the
21407                                     // top state as well, but only if there is not another
21408                                     // reason for it to be running.  Being on the top is a
21409                                     // special state, meaning you are specifically running
21410                                     // for the current top app.  If the process is already
21411                                     // running in the background for some other reason, it
21412                                     // is more important to continue considering it to be
21413                                     // in the background state.
21414                                     mayBeTop = true;
21415                                     mayBeTopType = "service";
21416                                     mayBeTopSource = cr.binding.client;
21417                                     mayBeTopTarget = s.name;
21418                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21419                                 } else {
21420                                     // Special handling for above-top states (persistent
21421                                     // processes).  These should not bring the current process
21422                                     // into the top state, since they are not on top.  Instead
21423                                     // give them the best state after that.
21424                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21425                                         clientProcState =
21426                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21427                                     } else if (mWakefulness
21428                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21429                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21430                                                     != 0) {
21431                                         clientProcState =
21432                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21433                                     } else {
21434                                         clientProcState =
21435                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21436                                     }
21437                                 }
21438                             }
21439                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21440                             if (clientProcState <
21441                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21442                                 clientProcState =
21443                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21444                             }
21445                         } else {
21446                             if (clientProcState <
21447                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21448                                 clientProcState =
21449                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21450                             }
21451                         }
21452                         if (procState > clientProcState) {
21453                             procState = clientProcState;
21454                             if (adjType == null) {
21455                                 adjType = "service";
21456                             }
21457                         }
21458                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21459                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21460                             app.pendingUiClean = true;
21461                         }
21462                         if (adjType != null) {
21463                             app.adjType = adjType;
21464                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21465                                     .REASON_SERVICE_IN_USE;
21466                             app.adjSource = cr.binding.client;
21467                             app.adjSourceProcState = clientProcState;
21468                             app.adjTarget = s.name;
21469                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21470                                     + ": " + app + ", due to " + cr.binding.client
21471                                     + " adj=" + adj + " procState=" + procState);
21472                         }
21473                     }
21474                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21475                         app.treatLikeActivity = true;
21476                     }
21477                     final ActivityRecord a = cr.activity;
21478                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21479                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21480                             (a.visible || a.state == ActivityState.RESUMED ||
21481                              a.state == ActivityState.PAUSING)) {
21482                             adj = ProcessList.FOREGROUND_APP_ADJ;
21483                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21484                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21485                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21486                                 } else {
21487                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21488                                 }
21489                             }
21490                             app.cached = false;
21491                             app.adjType = "service";
21492                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21493                                     .REASON_SERVICE_IN_USE;
21494                             app.adjSource = a;
21495                             app.adjSourceProcState = procState;
21496                             app.adjTarget = s.name;
21497                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21498                                     + app);
21499                         }
21500                     }
21501                 }
21502             }
21503         }
21504
21505         for (int provi = app.pubProviders.size()-1;
21506                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21507                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21508                         || procState > ActivityManager.PROCESS_STATE_TOP);
21509                 provi--) {
21510             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21511             for (int i = cpr.connections.size()-1;
21512                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21513                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21514                             || procState > ActivityManager.PROCESS_STATE_TOP);
21515                     i--) {
21516                 ContentProviderConnection conn = cpr.connections.get(i);
21517                 ProcessRecord client = conn.client;
21518                 if (client == app) {
21519                     // Being our own client is not interesting.
21520                     continue;
21521                 }
21522                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21523                 int clientProcState = client.curProcState;
21524                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21525                     // If the other app is cached for any reason, for purposes here
21526                     // we are going to consider it empty.
21527                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21528                 }
21529                 String adjType = null;
21530                 if (adj > clientAdj) {
21531                     if (app.hasShownUi && app != mHomeProcess
21532                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21533                         adjType = "cch-ui-provider";
21534                     } else {
21535                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21536                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21537                         adjType = "provider";
21538                     }
21539                     app.cached &= client.cached;
21540                 }
21541                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21542                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21543                         // Special handling of clients who are in the top state.
21544                         // We *may* want to consider this process to be in the
21545                         // top state as well, but only if there is not another
21546                         // reason for it to be running.  Being on the top is a
21547                         // special state, meaning you are specifically running
21548                         // for the current top app.  If the process is already
21549                         // running in the background for some other reason, it
21550                         // is more important to continue considering it to be
21551                         // in the background state.
21552                         mayBeTop = true;
21553                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21554                         mayBeTopType = adjType = "provider-top";
21555                         mayBeTopSource = client;
21556                         mayBeTopTarget = cpr.name;
21557                     } else {
21558                         // Special handling for above-top states (persistent
21559                         // processes).  These should not bring the current process
21560                         // into the top state, since they are not on top.  Instead
21561                         // give them the best state after that.
21562                         clientProcState =
21563                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21564                         if (adjType == null) {
21565                             adjType = "provider";
21566                         }
21567                     }
21568                 }
21569                 if (procState > clientProcState) {
21570                     procState = clientProcState;
21571                 }
21572                 if (client.curSchedGroup > schedGroup) {
21573                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21574                 }
21575                 if (adjType != null) {
21576                     app.adjType = adjType;
21577                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21578                             .REASON_PROVIDER_IN_USE;
21579                     app.adjSource = client;
21580                     app.adjSourceProcState = clientProcState;
21581                     app.adjTarget = cpr.name;
21582                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21583                             + ": " + app + ", due to " + client
21584                             + " adj=" + adj + " procState=" + procState);
21585                 }
21586             }
21587             // If the provider has external (non-framework) process
21588             // dependencies, ensure that its adjustment is at least
21589             // FOREGROUND_APP_ADJ.
21590             if (cpr.hasExternalProcessHandles()) {
21591                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21592                     adj = ProcessList.FOREGROUND_APP_ADJ;
21593                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21594                     app.cached = false;
21595                     app.adjType = "ext-provider";
21596                     app.adjTarget = cpr.name;
21597                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21598                 }
21599                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21600                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21601                 }
21602             }
21603         }
21604
21605         if (app.lastProviderTime > 0 &&
21606                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21607             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21608                 adj = ProcessList.PREVIOUS_APP_ADJ;
21609                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21610                 app.cached = false;
21611                 app.adjType = "recent-provider";
21612                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21613             }
21614             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21615                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21616                 app.adjType = "recent-provider";
21617                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21618             }
21619         }
21620
21621         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21622             // A client of one of our services or providers is in the top state.  We
21623             // *may* want to be in the top state, but not if we are already running in
21624             // the background for some other reason.  For the decision here, we are going
21625             // to pick out a few specific states that we want to remain in when a client
21626             // is top (states that tend to be longer-term) and otherwise allow it to go
21627             // to the top state.
21628             switch (procState) {
21629                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21630                     // Something else is keeping it at this level, just leave it.
21631                     break;
21632                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21633                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21634                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21635                 case ActivityManager.PROCESS_STATE_SERVICE:
21636                     // These all are longer-term states, so pull them up to the top
21637                     // of the background states, but not all the way to the top state.
21638                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21639                     app.adjType = mayBeTopType;
21640                     app.adjSource = mayBeTopSource;
21641                     app.adjTarget = mayBeTopTarget;
21642                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21643                             + ": " + app + ", due to " + mayBeTopSource
21644                             + " adj=" + adj + " procState=" + procState);
21645                     break;
21646                 default:
21647                     // Otherwise, top is a better choice, so take it.
21648                     procState = ActivityManager.PROCESS_STATE_TOP;
21649                     app.adjType = mayBeTopType;
21650                     app.adjSource = mayBeTopSource;
21651                     app.adjTarget = mayBeTopTarget;
21652                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21653                             + ": " + app + ", due to " + mayBeTopSource
21654                             + " adj=" + adj + " procState=" + procState);
21655                     break;
21656             }
21657         }
21658
21659         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21660             if (app.hasClientActivities) {
21661                 // This is a cached process, but with client activities.  Mark it so.
21662                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21663                 app.adjType = "cch-client-act";
21664             } else if (app.treatLikeActivity) {
21665                 // This is a cached process, but somebody wants us to treat it like it has
21666                 // an activity, okay!
21667                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21668                 app.adjType = "cch-as-act";
21669             }
21670         }
21671
21672         if (adj == ProcessList.SERVICE_ADJ) {
21673             if (doingAll) {
21674                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21675                 mNewNumServiceProcs++;
21676                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21677                 if (!app.serviceb) {
21678                     // This service isn't far enough down on the LRU list to
21679                     // normally be a B service, but if we are low on RAM and it
21680                     // is large we want to force it down since we would prefer to
21681                     // keep launcher over it.
21682                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21683                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21684                         app.serviceHighRam = true;
21685                         app.serviceb = true;
21686                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21687                     } else {
21688                         mNewNumAServiceProcs++;
21689                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21690                     }
21691                 } else {
21692                     app.serviceHighRam = false;
21693                 }
21694             }
21695             if (app.serviceb) {
21696                 adj = ProcessList.SERVICE_B_ADJ;
21697             }
21698         }
21699
21700         app.curRawAdj = adj;
21701
21702         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21703         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21704         if (adj > app.maxAdj) {
21705             adj = app.maxAdj;
21706             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21707                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21708             }
21709         }
21710
21711         // Do final modification to adj.  Everything we do between here and applying
21712         // the final setAdj must be done in this function, because we will also use
21713         // it when computing the final cached adj later.  Note that we don't need to
21714         // worry about this for max adj above, since max adj will always be used to
21715         // keep it out of the cached vaues.
21716         app.curAdj = app.modifyRawOomAdj(adj);
21717         app.curSchedGroup = schedGroup;
21718         app.curProcState = procState;
21719         app.foregroundActivities = foregroundActivities;
21720
21721         return app.curRawAdj;
21722     }
21723
21724     /**
21725      * Record new PSS sample for a process.
21726      */
21727     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21728             long now) {
21729         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21730                 swapPss * 1024);
21731         proc.lastPssTime = now;
21732         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21733         if (DEBUG_PSS) Slog.d(TAG_PSS,
21734                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21735                 + " state=" + ProcessList.makeProcStateString(procState));
21736         if (proc.initialIdlePss == 0) {
21737             proc.initialIdlePss = pss;
21738         }
21739         proc.lastPss = pss;
21740         proc.lastSwapPss = swapPss;
21741         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21742             proc.lastCachedPss = pss;
21743             proc.lastCachedSwapPss = swapPss;
21744         }
21745
21746         final SparseArray<Pair<Long, String>> watchUids
21747                 = mMemWatchProcesses.getMap().get(proc.processName);
21748         Long check = null;
21749         if (watchUids != null) {
21750             Pair<Long, String> val = watchUids.get(proc.uid);
21751             if (val == null) {
21752                 val = watchUids.get(0);
21753             }
21754             if (val != null) {
21755                 check = val.first;
21756             }
21757         }
21758         if (check != null) {
21759             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21760                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21761                 if (!isDebuggable) {
21762                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21763                         isDebuggable = true;
21764                     }
21765                 }
21766                 if (isDebuggable) {
21767                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21768                     final ProcessRecord myProc = proc;
21769                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21770                     mMemWatchDumpProcName = proc.processName;
21771                     mMemWatchDumpFile = heapdumpFile.toString();
21772                     mMemWatchDumpPid = proc.pid;
21773                     mMemWatchDumpUid = proc.uid;
21774                     BackgroundThread.getHandler().post(new Runnable() {
21775                         @Override
21776                         public void run() {
21777                             revokeUriPermission(ActivityThread.currentActivityThread()
21778                                             .getApplicationThread(),
21779                                     null, DumpHeapActivity.JAVA_URI,
21780                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21781                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21782                                     UserHandle.myUserId());
21783                             ParcelFileDescriptor fd = null;
21784                             try {
21785                                 heapdumpFile.delete();
21786                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21787                                         ParcelFileDescriptor.MODE_CREATE |
21788                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21789                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21790                                                 ParcelFileDescriptor.MODE_APPEND);
21791                                 IApplicationThread thread = myProc.thread;
21792                                 if (thread != null) {
21793                                     try {
21794                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21795                                                 "Requesting dump heap from "
21796                                                 + myProc + " to " + heapdumpFile);
21797                                         thread.dumpHeap(/* managed= */ true,
21798                                                 /* mallocInfo= */ false, /* runGc= */ false,
21799                                                 heapdumpFile.toString(), fd);
21800                                     } catch (RemoteException e) {
21801                                     }
21802                                 }
21803                             } catch (FileNotFoundException e) {
21804                                 e.printStackTrace();
21805                             } finally {
21806                                 if (fd != null) {
21807                                     try {
21808                                         fd.close();
21809                                     } catch (IOException e) {
21810                                     }
21811                                 }
21812                             }
21813                         }
21814                     });
21815                 } else {
21816                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21817                             + ", but debugging not enabled");
21818                 }
21819             }
21820         }
21821     }
21822
21823     /**
21824      * Schedule PSS collection of a process.
21825      */
21826     void requestPssLocked(ProcessRecord proc, int procState) {
21827         if (mPendingPssProcesses.contains(proc)) {
21828             return;
21829         }
21830         if (mPendingPssProcesses.size() == 0) {
21831             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21832         }
21833         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21834         proc.pssProcState = procState;
21835         mPendingPssProcesses.add(proc);
21836     }
21837
21838     /**
21839      * Schedule PSS collection of all processes.
21840      */
21841     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21842         if (!always) {
21843             if (now < (mLastFullPssTime +
21844                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21845                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21846                 return;
21847             }
21848         }
21849         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21850         mLastFullPssTime = now;
21851         mFullPssPending = true;
21852         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21853         mPendingPssProcesses.clear();
21854         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21855             ProcessRecord app = mLruProcesses.get(i);
21856             if (app.thread == null
21857                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21858                 continue;
21859             }
21860             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21861                 app.pssProcState = app.setProcState;
21862                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21863                         mTestPssMode, isSleepingLocked(), now);
21864                 mPendingPssProcesses.add(app);
21865             }
21866         }
21867         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21868     }
21869
21870     public void setTestPssMode(boolean enabled) {
21871         synchronized (this) {
21872             mTestPssMode = enabled;
21873             if (enabled) {
21874                 // Whenever we enable the mode, we want to take a snapshot all of current
21875                 // process mem use.
21876                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21877             }
21878         }
21879     }
21880
21881     /**
21882      * Ask a given process to GC right now.
21883      */
21884     final void performAppGcLocked(ProcessRecord app) {
21885         try {
21886             app.lastRequestedGc = SystemClock.uptimeMillis();
21887             if (app.thread != null) {
21888                 if (app.reportLowMemory) {
21889                     app.reportLowMemory = false;
21890                     app.thread.scheduleLowMemory();
21891                 } else {
21892                     app.thread.processInBackground();
21893                 }
21894             }
21895         } catch (Exception e) {
21896             // whatever.
21897         }
21898     }
21899
21900     /**
21901      * Returns true if things are idle enough to perform GCs.
21902      */
21903     private final boolean canGcNowLocked() {
21904         boolean processingBroadcasts = false;
21905         for (BroadcastQueue q : mBroadcastQueues) {
21906             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21907                 processingBroadcasts = true;
21908             }
21909         }
21910         return !processingBroadcasts
21911                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21912     }
21913
21914     /**
21915      * Perform GCs on all processes that are waiting for it, but only
21916      * if things are idle.
21917      */
21918     final void performAppGcsLocked() {
21919         final int N = mProcessesToGc.size();
21920         if (N <= 0) {
21921             return;
21922         }
21923         if (canGcNowLocked()) {
21924             while (mProcessesToGc.size() > 0) {
21925                 ProcessRecord proc = mProcessesToGc.remove(0);
21926                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21927                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21928                             <= SystemClock.uptimeMillis()) {
21929                         // To avoid spamming the system, we will GC processes one
21930                         // at a time, waiting a few seconds between each.
21931                         performAppGcLocked(proc);
21932                         scheduleAppGcsLocked();
21933                         return;
21934                     } else {
21935                         // It hasn't been long enough since we last GCed this
21936                         // process...  put it in the list to wait for its time.
21937                         addProcessToGcListLocked(proc);
21938                         break;
21939                     }
21940                 }
21941             }
21942
21943             scheduleAppGcsLocked();
21944         }
21945     }
21946
21947     /**
21948      * If all looks good, perform GCs on all processes waiting for them.
21949      */
21950     final void performAppGcsIfAppropriateLocked() {
21951         if (canGcNowLocked()) {
21952             performAppGcsLocked();
21953             return;
21954         }
21955         // Still not idle, wait some more.
21956         scheduleAppGcsLocked();
21957     }
21958
21959     /**
21960      * Schedule the execution of all pending app GCs.
21961      */
21962     final void scheduleAppGcsLocked() {
21963         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21964
21965         if (mProcessesToGc.size() > 0) {
21966             // Schedule a GC for the time to the next process.
21967             ProcessRecord proc = mProcessesToGc.get(0);
21968             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21969
21970             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21971             long now = SystemClock.uptimeMillis();
21972             if (when < (now+mConstants.GC_TIMEOUT)) {
21973                 when = now + mConstants.GC_TIMEOUT;
21974             }
21975             mHandler.sendMessageAtTime(msg, when);
21976         }
21977     }
21978
21979     /**
21980      * Add a process to the array of processes waiting to be GCed.  Keeps the
21981      * list in sorted order by the last GC time.  The process can't already be
21982      * on the list.
21983      */
21984     final void addProcessToGcListLocked(ProcessRecord proc) {
21985         boolean added = false;
21986         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21987             if (mProcessesToGc.get(i).lastRequestedGc <
21988                     proc.lastRequestedGc) {
21989                 added = true;
21990                 mProcessesToGc.add(i+1, proc);
21991                 break;
21992             }
21993         }
21994         if (!added) {
21995             mProcessesToGc.add(0, proc);
21996         }
21997     }
21998
21999     /**
22000      * Set up to ask a process to GC itself.  This will either do it
22001      * immediately, or put it on the list of processes to gc the next
22002      * time things are idle.
22003      */
22004     final void scheduleAppGcLocked(ProcessRecord app) {
22005         long now = SystemClock.uptimeMillis();
22006         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
22007             return;
22008         }
22009         if (!mProcessesToGc.contains(app)) {
22010             addProcessToGcListLocked(app);
22011             scheduleAppGcsLocked();
22012         }
22013     }
22014
22015     final void checkExcessivePowerUsageLocked() {
22016         updateCpuStatsNow();
22017
22018         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22019         boolean doCpuKills = true;
22020         if (mLastPowerCheckUptime == 0) {
22021             doCpuKills = false;
22022         }
22023         final long curUptime = SystemClock.uptimeMillis();
22024         final long uptimeSince = curUptime - mLastPowerCheckUptime;
22025         mLastPowerCheckUptime = curUptime;
22026         int i = mLruProcesses.size();
22027         while (i > 0) {
22028             i--;
22029             ProcessRecord app = mLruProcesses.get(i);
22030             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22031                 if (app.lastCpuTime <= 0) {
22032                     continue;
22033                 }
22034                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
22035                 if (DEBUG_POWER) {
22036                     StringBuilder sb = new StringBuilder(128);
22037                     sb.append("CPU for ");
22038                     app.toShortString(sb);
22039                     sb.append(": over ");
22040                     TimeUtils.formatDuration(uptimeSince, sb);
22041                     sb.append(" used ");
22042                     TimeUtils.formatDuration(cputimeUsed, sb);
22043                     sb.append(" (");
22044                     sb.append((cputimeUsed*100)/uptimeSince);
22045                     sb.append("%)");
22046                     Slog.i(TAG_POWER, sb.toString());
22047                 }
22048                 // If the process has used too much CPU over the last duration, the
22049                 // user probably doesn't want this, so kill!
22050                 if (doCpuKills && uptimeSince > 0) {
22051                     // What is the limit for this process?
22052                     int cpuLimit;
22053                     long checkDur = curUptime - app.whenUnimportant;
22054                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
22055                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
22056                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
22057                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
22058                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
22059                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
22060                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
22061                     } else {
22062                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
22063                     }
22064                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22065                         synchronized (stats) {
22066                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22067                                     uptimeSince, cputimeUsed);
22068                         }
22069                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22070                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22071                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22072                     }
22073                 }
22074                 app.lastCpuTime = app.curCpuTime;
22075             }
22076         }
22077     }
22078
22079     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22080             long nowElapsed) {
22081         boolean success = true;
22082
22083         if (app.curRawAdj != app.setRawAdj) {
22084             app.setRawAdj = app.curRawAdj;
22085         }
22086
22087         int changes = 0;
22088
22089         if (app.curAdj != app.setAdj) {
22090             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22091             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22092                 String msg = "Set " + app.pid + " " + app.processName + " adj "
22093                         + app.curAdj + ": " + app.adjType;
22094                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22095             }
22096             app.setAdj = app.curAdj;
22097             app.verifiedAdj = ProcessList.INVALID_ADJ;
22098         }
22099
22100         if (app.setSchedGroup != app.curSchedGroup) {
22101             int oldSchedGroup = app.setSchedGroup;
22102             app.setSchedGroup = app.curSchedGroup;
22103             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22104                 String msg = "Setting sched group of " + app.processName
22105                         + " to " + app.curSchedGroup;
22106                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22107             }
22108             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22109                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22110                 app.kill(app.waitingToKill, true);
22111                 success = false;
22112             } else {
22113                 int processGroup;
22114                 switch (app.curSchedGroup) {
22115                     case ProcessList.SCHED_GROUP_BACKGROUND:
22116                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22117                         break;
22118                     case ProcessList.SCHED_GROUP_TOP_APP:
22119                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22120                         processGroup = THREAD_GROUP_TOP_APP;
22121                         break;
22122                     default:
22123                         processGroup = THREAD_GROUP_DEFAULT;
22124                         break;
22125                 }
22126                 long oldId = Binder.clearCallingIdentity();
22127                 try {
22128                     setProcessGroup(app.pid, processGroup);
22129                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22130                         // do nothing if we already switched to RT
22131                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22132                             mVrController.onTopProcChangedLocked(app);
22133                             if (mUseFifoUiScheduling) {
22134                                 // Switch UI pipeline for app to SCHED_FIFO
22135                                 app.savedPriority = Process.getThreadPriority(app.pid);
22136                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22137                                 if (app.renderThreadTid != 0) {
22138                                     scheduleAsFifoPriority(app.renderThreadTid,
22139                                         /* suppressLogs */true);
22140                                     if (DEBUG_OOM_ADJ) {
22141                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22142                                             app.renderThreadTid + ") to FIFO");
22143                                     }
22144                                 } else {
22145                                     if (DEBUG_OOM_ADJ) {
22146                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22147                                     }
22148                                 }
22149                             } else {
22150                                 // Boost priority for top app UI and render threads
22151                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22152                                 if (app.renderThreadTid != 0) {
22153                                     try {
22154                                         setThreadPriority(app.renderThreadTid,
22155                                                 TOP_APP_PRIORITY_BOOST);
22156                                     } catch (IllegalArgumentException e) {
22157                                         // thread died, ignore
22158                                     }
22159                                 }
22160                             }
22161                         }
22162                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22163                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22164                         mVrController.onTopProcChangedLocked(app);
22165                         if (mUseFifoUiScheduling) {
22166                             try {
22167                                 // Reset UI pipeline to SCHED_OTHER
22168                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22169                                 setThreadPriority(app.pid, app.savedPriority);
22170                                 if (app.renderThreadTid != 0) {
22171                                     setThreadScheduler(app.renderThreadTid,
22172                                         SCHED_OTHER, 0);
22173                                     setThreadPriority(app.renderThreadTid, -4);
22174                                 }
22175                             } catch (IllegalArgumentException e) {
22176                                 Slog.w(TAG,
22177                                         "Failed to set scheduling policy, thread does not exist:\n"
22178                                                 + e);
22179                             } catch (SecurityException e) {
22180                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22181                             }
22182                         } else {
22183                             // Reset priority for top app UI and render threads
22184                             setThreadPriority(app.pid, 0);
22185                             if (app.renderThreadTid != 0) {
22186                                 setThreadPriority(app.renderThreadTid, 0);
22187                             }
22188                         }
22189                     }
22190                 } catch (Exception e) {
22191                     if (false) {
22192                         Slog.w(TAG, "Failed setting process group of " + app.pid
22193                                 + " to " + app.curSchedGroup);
22194                         Slog.w(TAG, "at location", e);
22195                     }
22196                 } finally {
22197                     Binder.restoreCallingIdentity(oldId);
22198                 }
22199             }
22200         }
22201         if (app.repForegroundActivities != app.foregroundActivities) {
22202             app.repForegroundActivities = app.foregroundActivities;
22203             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22204         }
22205         if (app.repProcState != app.curProcState) {
22206             app.repProcState = app.curProcState;
22207             if (app.thread != null) {
22208                 try {
22209                     if (false) {
22210                         //RuntimeException h = new RuntimeException("here");
22211                         Slog.i(TAG, "Sending new process state " + app.repProcState
22212                                 + " to " + app /*, h*/);
22213                     }
22214                     app.thread.setProcessState(app.repProcState);
22215                 } catch (RemoteException e) {
22216                 }
22217             }
22218         }
22219         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22220                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22221             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22222                 // Experimental code to more aggressively collect pss while
22223                 // running test...  the problem is that this tends to collect
22224                 // the data right when a process is transitioning between process
22225                 // states, which well tend to give noisy data.
22226                 long start = SystemClock.uptimeMillis();
22227                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22228                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22229                 mPendingPssProcesses.remove(app);
22230                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22231                         + " to " + app.curProcState + ": "
22232                         + (SystemClock.uptimeMillis()-start) + "ms");
22233             }
22234             app.lastStateTime = now;
22235             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22236                     mTestPssMode, isSleepingLocked(), now);
22237             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22238                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22239                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22240                     + (app.nextPssTime-now) + ": " + app);
22241         } else {
22242             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22243                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22244                     mTestPssMode)))) {
22245                 requestPssLocked(app, app.setProcState);
22246                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22247                         mTestPssMode, isSleepingLocked(), now);
22248             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22249                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22250         }
22251         if (app.setProcState != app.curProcState) {
22252             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22253                 String msg = "Proc state change of " + app.processName
22254                         + " to " + app.curProcState;
22255                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22256             }
22257             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22258             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22259             if (setImportant && !curImportant) {
22260                 // This app is no longer something we consider important enough to allow to
22261                 // use arbitrary amounts of battery power.  Note
22262                 // its current CPU time to later know to kill it if
22263                 // it is not behaving well.
22264                 app.whenUnimportant = now;
22265                 app.lastCpuTime = 0;
22266             }
22267             // Inform UsageStats of important process state change
22268             // Must be called before updating setProcState
22269             maybeUpdateUsageStatsLocked(app, nowElapsed);
22270
22271             app.setProcState = app.curProcState;
22272             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22273                 app.notCachedSinceIdle = false;
22274             }
22275             if (!doingAll) {
22276                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22277             } else {
22278                 app.procStateChanged = true;
22279             }
22280         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22281                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22282             // For apps that sit around for a long time in the interactive state, we need
22283             // to report this at least once a day so they don't go idle.
22284             maybeUpdateUsageStatsLocked(app, nowElapsed);
22285         }
22286
22287         if (changes != 0) {
22288             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22289                     "Changes in " + app + ": " + changes);
22290             int i = mPendingProcessChanges.size()-1;
22291             ProcessChangeItem item = null;
22292             while (i >= 0) {
22293                 item = mPendingProcessChanges.get(i);
22294                 if (item.pid == app.pid) {
22295                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22296                             "Re-using existing item: " + item);
22297                     break;
22298                 }
22299                 i--;
22300             }
22301             if (i < 0) {
22302                 // No existing item in pending changes; need a new one.
22303                 final int NA = mAvailProcessChanges.size();
22304                 if (NA > 0) {
22305                     item = mAvailProcessChanges.remove(NA-1);
22306                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22307                             "Retrieving available item: " + item);
22308                 } else {
22309                     item = new ProcessChangeItem();
22310                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22311                             "Allocating new item: " + item);
22312                 }
22313                 item.changes = 0;
22314                 item.pid = app.pid;
22315                 item.uid = app.info.uid;
22316                 if (mPendingProcessChanges.size() == 0) {
22317                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22318                             "*** Enqueueing dispatch processes changed!");
22319                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22320                 }
22321                 mPendingProcessChanges.add(item);
22322             }
22323             item.changes |= changes;
22324             item.foregroundActivities = app.repForegroundActivities;
22325             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22326                     "Item " + Integer.toHexString(System.identityHashCode(item))
22327                     + " " + app.toShortString() + ": changes=" + item.changes
22328                     + " foreground=" + item.foregroundActivities
22329                     + " type=" + app.adjType + " source=" + app.adjSource
22330                     + " target=" + app.adjTarget);
22331         }
22332
22333         return success;
22334     }
22335
22336     private boolean isEphemeralLocked(int uid) {
22337         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22338         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22339             return false;
22340         }
22341         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22342                 packages[0]);
22343     }
22344
22345     @VisibleForTesting
22346     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22347         final UidRecord.ChangeItem pendingChange;
22348         if (uidRec == null || uidRec.pendingChange == null) {
22349             if (mPendingUidChanges.size() == 0) {
22350                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22351                         "*** Enqueueing dispatch uid changed!");
22352                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22353             }
22354             final int NA = mAvailUidChanges.size();
22355             if (NA > 0) {
22356                 pendingChange = mAvailUidChanges.remove(NA-1);
22357                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22358                         "Retrieving available item: " + pendingChange);
22359             } else {
22360                 pendingChange = new UidRecord.ChangeItem();
22361                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22362                         "Allocating new item: " + pendingChange);
22363             }
22364             if (uidRec != null) {
22365                 uidRec.pendingChange = pendingChange;
22366                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22367                     // If this uid is going away, and we haven't yet reported it is gone,
22368                     // then do so now.
22369                     change |= UidRecord.CHANGE_IDLE;
22370                 }
22371             } else if (uid < 0) {
22372                 throw new IllegalArgumentException("No UidRecord or uid");
22373             }
22374             pendingChange.uidRecord = uidRec;
22375             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22376             mPendingUidChanges.add(pendingChange);
22377         } else {
22378             pendingChange = uidRec.pendingChange;
22379             // If there is no change in idle or active state, then keep whatever was pending.
22380             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22381                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22382                         | UidRecord.CHANGE_ACTIVE));
22383             }
22384             // If there is no change in cached or uncached state, then keep whatever was pending.
22385             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22386                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22387                         | UidRecord.CHANGE_UNCACHED));
22388             }
22389             // If this is a report of the UID being gone, then we shouldn't keep any previous
22390             // report of it being active or cached.  (That is, a gone uid is never active,
22391             // and never cached.)
22392             if ((change & UidRecord.CHANGE_GONE) != 0) {
22393                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22394                 if (!uidRec.idle) {
22395                     // If this uid is going away, and we haven't yet reported it is gone,
22396                     // then do so now.
22397                     change |= UidRecord.CHANGE_IDLE;
22398                 }
22399             }
22400         }
22401         pendingChange.change = change;
22402         pendingChange.processState = uidRec != null
22403                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22404         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22405         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22406         if (uidRec != null) {
22407             uidRec.lastReportedChange = change;
22408             uidRec.updateLastDispatchedProcStateSeq(change);
22409         }
22410
22411         // Directly update the power manager, since we sit on top of it and it is critical
22412         // it be kept in sync (so wake locks will be held as soon as appropriate).
22413         if (mLocalPowerManager != null) {
22414             // TO DO: dispatch cached/uncached changes here, so we don't need to report
22415             // all proc state changes.
22416             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22417                 mLocalPowerManager.uidActive(pendingChange.uid);
22418             }
22419             if ((change & UidRecord.CHANGE_IDLE) != 0) {
22420                 mLocalPowerManager.uidIdle(pendingChange.uid);
22421             }
22422             if ((change & UidRecord.CHANGE_GONE) != 0) {
22423                 mLocalPowerManager.uidGone(pendingChange.uid);
22424             } else {
22425                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22426                         pendingChange.processState);
22427             }
22428         }
22429     }
22430
22431     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22432             String authority) {
22433         if (app == null) return;
22434         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22435             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22436             if (userState == null) return;
22437             final long now = SystemClock.elapsedRealtime();
22438             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22439             if (lastReported == null || lastReported < now - 60 * 1000L) {
22440                 if (mSystemReady) {
22441                     // Cannot touch the user stats if not system ready
22442                     mUsageStatsService.reportContentProviderUsage(
22443                             authority, providerPkgName, app.userId);
22444                 }
22445                 userState.mProviderLastReportedFg.put(authority, now);
22446             }
22447         }
22448     }
22449
22450     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22451         if (DEBUG_USAGE_STATS) {
22452             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22453                     + "] state changes: old = " + app.setProcState + ", new = "
22454                     + app.curProcState);
22455         }
22456         if (mUsageStatsService == null) {
22457             return;
22458         }
22459         boolean isInteraction;
22460         // To avoid some abuse patterns, we are going to be careful about what we consider
22461         // to be an app interaction.  Being the top activity doesn't count while the display
22462         // is sleeping, nor do short foreground services.
22463         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22464             isInteraction = true;
22465             app.fgInteractionTime = 0;
22466         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22467             if (app.fgInteractionTime == 0) {
22468                 app.fgInteractionTime = nowElapsed;
22469                 isInteraction = false;
22470             } else {
22471                 isInteraction = nowElapsed > app.fgInteractionTime
22472                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22473             }
22474         } else {
22475             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22476             app.fgInteractionTime = 0;
22477         }
22478         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22479                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22480             app.interactionEventTime = nowElapsed;
22481             String[] packages = app.getPackageList();
22482             if (packages != null) {
22483                 for (int i = 0; i < packages.length; i++) {
22484                     mUsageStatsService.reportEvent(packages[i], app.userId,
22485                             UsageEvents.Event.SYSTEM_INTERACTION);
22486                 }
22487             }
22488         }
22489         app.reportedInteraction = isInteraction;
22490         if (!isInteraction) {
22491             app.interactionEventTime = 0;
22492         }
22493     }
22494
22495     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22496         if (proc.thread != null) {
22497             if (proc.baseProcessTracker != null) {
22498                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22499             }
22500         }
22501     }
22502
22503     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22504             ProcessRecord TOP_APP, boolean doingAll, long now) {
22505         if (app.thread == null) {
22506             return false;
22507         }
22508
22509         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22510
22511         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22512     }
22513
22514     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22515             boolean oomAdj) {
22516         if (isForeground != proc.foregroundServices) {
22517             proc.foregroundServices = isForeground;
22518             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22519                     proc.info.uid);
22520             if (isForeground) {
22521                 if (curProcs == null) {
22522                     curProcs = new ArrayList<ProcessRecord>();
22523                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22524                 }
22525                 if (!curProcs.contains(proc)) {
22526                     curProcs.add(proc);
22527                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22528                             proc.info.packageName, proc.info.uid);
22529                 }
22530             } else {
22531                 if (curProcs != null) {
22532                     if (curProcs.remove(proc)) {
22533                         mBatteryStatsService.noteEvent(
22534                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22535                                 proc.info.packageName, proc.info.uid);
22536                         if (curProcs.size() <= 0) {
22537                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22538                         }
22539                     }
22540                 }
22541             }
22542             if (oomAdj) {
22543                 updateOomAdjLocked();
22544             }
22545         }
22546     }
22547
22548     private final ActivityRecord resumedAppLocked() {
22549         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22550         String pkg;
22551         int uid;
22552         if (act != null) {
22553             pkg = act.packageName;
22554             uid = act.info.applicationInfo.uid;
22555         } else {
22556             pkg = null;
22557             uid = -1;
22558         }
22559         // Has the UID or resumed package name changed?
22560         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22561                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22562             if (mCurResumedPackage != null) {
22563                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22564                         mCurResumedPackage, mCurResumedUid);
22565             }
22566             mCurResumedPackage = pkg;
22567             mCurResumedUid = uid;
22568             if (mCurResumedPackage != null) {
22569                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22570                         mCurResumedPackage, mCurResumedUid);
22571             }
22572         }
22573         return act;
22574     }
22575
22576     /**
22577      * Update OomAdj for a specific process.
22578      * @param app The process to update
22579      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22580      *                  if necessary, or skip.
22581      * @return whether updateOomAdjLocked(app) was successful.
22582      */
22583     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22584         final ActivityRecord TOP_ACT = resumedAppLocked();
22585         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22586         final boolean wasCached = app.cached;
22587
22588         mAdjSeq++;
22589
22590         // This is the desired cached adjusment we want to tell it to use.
22591         // If our app is currently cached, we know it, and that is it.  Otherwise,
22592         // we don't know it yet, and it needs to now be cached we will then
22593         // need to do a complete oom adj.
22594         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22595                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22596         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22597                 SystemClock.uptimeMillis());
22598         if (oomAdjAll
22599                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22600             // Changed to/from cached state, so apps after it in the LRU
22601             // list may also be changed.
22602             updateOomAdjLocked();
22603         }
22604         return success;
22605     }
22606
22607     final void updateOomAdjLocked() {
22608         final ActivityRecord TOP_ACT = resumedAppLocked();
22609         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22610         final long now = SystemClock.uptimeMillis();
22611         final long nowElapsed = SystemClock.elapsedRealtime();
22612         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22613         final int N = mLruProcesses.size();
22614
22615         if (false) {
22616             RuntimeException e = new RuntimeException();
22617             e.fillInStackTrace();
22618             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22619         }
22620
22621         // Reset state in all uid records.
22622         for (int i=mActiveUids.size()-1; i>=0; i--) {
22623             final UidRecord uidRec = mActiveUids.valueAt(i);
22624             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22625                     "Starting update of " + uidRec);
22626             uidRec.reset();
22627         }
22628
22629         mStackSupervisor.rankTaskLayersIfNeeded();
22630
22631         mAdjSeq++;
22632         mNewNumServiceProcs = 0;
22633         mNewNumAServiceProcs = 0;
22634
22635         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22636         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22637
22638         // Let's determine how many processes we have running vs.
22639         // how many slots we have for background processes; we may want
22640         // to put multiple processes in a slot of there are enough of
22641         // them.
22642         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22643                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22644         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22645         if (numEmptyProcs > cachedProcessLimit) {
22646             // If there are more empty processes than our limit on cached
22647             // processes, then use the cached process limit for the factor.
22648             // This ensures that the really old empty processes get pushed
22649             // down to the bottom, so if we are running low on memory we will
22650             // have a better chance at keeping around more cached processes
22651             // instead of a gazillion empty processes.
22652             numEmptyProcs = cachedProcessLimit;
22653         }
22654         int emptyFactor = numEmptyProcs/numSlots;
22655         if (emptyFactor < 1) emptyFactor = 1;
22656         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22657         if (cachedFactor < 1) cachedFactor = 1;
22658         int stepCached = 0;
22659         int stepEmpty = 0;
22660         int numCached = 0;
22661         int numEmpty = 0;
22662         int numTrimming = 0;
22663
22664         mNumNonCachedProcs = 0;
22665         mNumCachedHiddenProcs = 0;
22666
22667         // First update the OOM adjustment for each of the
22668         // application processes based on their current state.
22669         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22670         int nextCachedAdj = curCachedAdj+1;
22671         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22672         int nextEmptyAdj = curEmptyAdj+2;
22673         for (int i=N-1; i>=0; i--) {
22674             ProcessRecord app = mLruProcesses.get(i);
22675             if (!app.killedByAm && app.thread != null) {
22676                 app.procStateChanged = false;
22677                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22678
22679                 // If we haven't yet assigned the final cached adj
22680                 // to the process, do that now.
22681                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22682                     switch (app.curProcState) {
22683                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22684                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22685                             // This process is a cached process holding activities...
22686                             // assign it the next cached value for that type, and then
22687                             // step that cached level.
22688                             app.curRawAdj = curCachedAdj;
22689                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22690                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22691                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22692                                     + ")");
22693                             if (curCachedAdj != nextCachedAdj) {
22694                                 stepCached++;
22695                                 if (stepCached >= cachedFactor) {
22696                                     stepCached = 0;
22697                                     curCachedAdj = nextCachedAdj;
22698                                     nextCachedAdj += 2;
22699                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22700                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22701                                     }
22702                                 }
22703                             }
22704                             break;
22705                         default:
22706                             // For everything else, assign next empty cached process
22707                             // level and bump that up.  Note that this means that
22708                             // long-running services that have dropped down to the
22709                             // cached level will be treated as empty (since their process
22710                             // state is still as a service), which is what we want.
22711                             app.curRawAdj = curEmptyAdj;
22712                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22713                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22714                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22715                                     + ")");
22716                             if (curEmptyAdj != nextEmptyAdj) {
22717                                 stepEmpty++;
22718                                 if (stepEmpty >= emptyFactor) {
22719                                     stepEmpty = 0;
22720                                     curEmptyAdj = nextEmptyAdj;
22721                                     nextEmptyAdj += 2;
22722                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22723                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22724                                     }
22725                                 }
22726                             }
22727                             break;
22728                     }
22729                 }
22730
22731                 applyOomAdjLocked(app, true, now, nowElapsed);
22732
22733                 // Count the number of process types.
22734                 switch (app.curProcState) {
22735                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22736                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22737                         mNumCachedHiddenProcs++;
22738                         numCached++;
22739                         if (numCached > cachedProcessLimit) {
22740                             app.kill("cached #" + numCached, true);
22741                         }
22742                         break;
22743                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22744                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22745                                 && app.lastActivityTime < oldTime) {
22746                             app.kill("empty for "
22747                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22748                                     / 1000) + "s", true);
22749                         } else {
22750                             numEmpty++;
22751                             if (numEmpty > emptyProcessLimit) {
22752                                 app.kill("empty #" + numEmpty, true);
22753                             }
22754                         }
22755                         break;
22756                     default:
22757                         mNumNonCachedProcs++;
22758                         break;
22759                 }
22760
22761                 if (app.isolated && app.services.size() <= 0) {
22762                     // If this is an isolated process, and there are no
22763                     // services running in it, then the process is no longer
22764                     // needed.  We agressively kill these because we can by
22765                     // definition not re-use the same process again, and it is
22766                     // good to avoid having whatever code was running in them
22767                     // left sitting around after no longer needed.
22768                     app.kill("isolated not needed", true);
22769                 } else {
22770                     // Keeping this process, update its uid.
22771                     final UidRecord uidRec = app.uidRecord;
22772                     if (uidRec != null) {
22773                         uidRec.ephemeral = app.info.isInstantApp();
22774                         if (uidRec.curProcState > app.curProcState) {
22775                             uidRec.curProcState = app.curProcState;
22776                         }
22777                         if (app.foregroundServices) {
22778                             uidRec.foregroundServices = true;
22779                         }
22780                     }
22781                 }
22782
22783                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22784                         && !app.killedByAm) {
22785                     numTrimming++;
22786                 }
22787             }
22788         }
22789
22790         incrementProcStateSeqAndNotifyAppsLocked();
22791
22792         mNumServiceProcs = mNewNumServiceProcs;
22793
22794         // Now determine the memory trimming level of background processes.
22795         // Unfortunately we need to start at the back of the list to do this
22796         // properly.  We only do this if the number of background apps we
22797         // are managing to keep around is less than half the maximum we desire;
22798         // if we are keeping a good number around, we'll let them use whatever
22799         // memory they want.
22800         final int numCachedAndEmpty = numCached + numEmpty;
22801         int memFactor;
22802         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22803                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22804             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22805                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22806             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22807                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22808             } else {
22809                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22810             }
22811         } else {
22812             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22813         }
22814         // We always allow the memory level to go up (better).  We only allow it to go
22815         // down if we are in a state where that is allowed, *and* the total number of processes
22816         // has gone down since last time.
22817         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22818                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22819                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22820         if (memFactor > mLastMemoryLevel) {
22821             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22822                 memFactor = mLastMemoryLevel;
22823                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22824             }
22825         }
22826         if (memFactor != mLastMemoryLevel) {
22827             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22828         }
22829         mLastMemoryLevel = memFactor;
22830         mLastNumProcesses = mLruProcesses.size();
22831         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22832         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22833         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22834             if (mLowRamStartTime == 0) {
22835                 mLowRamStartTime = now;
22836             }
22837             int step = 0;
22838             int fgTrimLevel;
22839             switch (memFactor) {
22840                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22841                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22842                     break;
22843                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22844                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22845                     break;
22846                 default:
22847                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22848                     break;
22849             }
22850             int factor = numTrimming/3;
22851             int minFactor = 2;
22852             if (mHomeProcess != null) minFactor++;
22853             if (mPreviousProcess != null) minFactor++;
22854             if (factor < minFactor) factor = minFactor;
22855             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22856             for (int i=N-1; i>=0; i--) {
22857                 ProcessRecord app = mLruProcesses.get(i);
22858                 if (allChanged || app.procStateChanged) {
22859                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22860                     app.procStateChanged = false;
22861                 }
22862                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22863                         && !app.killedByAm) {
22864                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22865                         try {
22866                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22867                                     "Trimming memory of " + app.processName + " to " + curLevel);
22868                             app.thread.scheduleTrimMemory(curLevel);
22869                         } catch (RemoteException e) {
22870                         }
22871                         if (false) {
22872                             // For now we won't do this; our memory trimming seems
22873                             // to be good enough at this point that destroying
22874                             // activities causes more harm than good.
22875                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22876                                     && app != mHomeProcess && app != mPreviousProcess) {
22877                                 // Need to do this on its own message because the stack may not
22878                                 // be in a consistent state at this point.
22879                                 // For these apps we will also finish their activities
22880                                 // to help them free memory.
22881                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22882                             }
22883                         }
22884                     }
22885                     app.trimMemoryLevel = curLevel;
22886                     step++;
22887                     if (step >= factor) {
22888                         step = 0;
22889                         switch (curLevel) {
22890                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22891                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22892                                 break;
22893                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22894                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22895                                 break;
22896                         }
22897                     }
22898                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22899                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22900                             && app.thread != null) {
22901                         try {
22902                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22903                                     "Trimming memory of heavy-weight " + app.processName
22904                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22905                             app.thread.scheduleTrimMemory(
22906                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22907                         } catch (RemoteException e) {
22908                         }
22909                     }
22910                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22911                 } else {
22912                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22913                             || app.systemNoUi) && app.pendingUiClean) {
22914                         // If this application is now in the background and it
22915                         // had done UI, then give it the special trim level to
22916                         // have it free UI resources.
22917                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22918                         if (app.trimMemoryLevel < level && app.thread != null) {
22919                             try {
22920                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22921                                         "Trimming memory of bg-ui " + app.processName
22922                                         + " to " + level);
22923                                 app.thread.scheduleTrimMemory(level);
22924                             } catch (RemoteException e) {
22925                             }
22926                         }
22927                         app.pendingUiClean = false;
22928                     }
22929                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22930                         try {
22931                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22932                                     "Trimming memory of fg " + app.processName
22933                                     + " to " + fgTrimLevel);
22934                             app.thread.scheduleTrimMemory(fgTrimLevel);
22935                         } catch (RemoteException e) {
22936                         }
22937                     }
22938                     app.trimMemoryLevel = fgTrimLevel;
22939                 }
22940             }
22941         } else {
22942             if (mLowRamStartTime != 0) {
22943                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22944                 mLowRamStartTime = 0;
22945             }
22946             for (int i=N-1; i>=0; i--) {
22947                 ProcessRecord app = mLruProcesses.get(i);
22948                 if (allChanged || app.procStateChanged) {
22949                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22950                     app.procStateChanged = false;
22951                 }
22952                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22953                         || app.systemNoUi) && app.pendingUiClean) {
22954                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22955                             && app.thread != null) {
22956                         try {
22957                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22958                                     "Trimming memory of ui hidden " + app.processName
22959                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22960                             app.thread.scheduleTrimMemory(
22961                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22962                         } catch (RemoteException e) {
22963                         }
22964                     }
22965                     app.pendingUiClean = false;
22966                 }
22967                 app.trimMemoryLevel = 0;
22968             }
22969         }
22970
22971         if (mAlwaysFinishActivities) {
22972             // Need to do this on its own message because the stack may not
22973             // be in a consistent state at this point.
22974             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22975         }
22976
22977         if (allChanged) {
22978             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22979         }
22980
22981         ArrayList<UidRecord> becameIdle = null;
22982
22983         // Update from any uid changes.
22984         if (mLocalPowerManager != null) {
22985             mLocalPowerManager.startUidChanges();
22986         }
22987         for (int i=mActiveUids.size()-1; i>=0; i--) {
22988             final UidRecord uidRec = mActiveUids.valueAt(i);
22989             int uidChange = UidRecord.CHANGE_PROCSTATE;
22990             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22991                     && (uidRec.setProcState != uidRec.curProcState
22992                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
22993                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22994                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22995                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22996                         + " to " + uidRec.curWhitelist);
22997                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22998                         && !uidRec.curWhitelist) {
22999                     // UID is now in the background (and not on the temp whitelist).  Was it
23000                     // previously in the foreground (or on the temp whitelist)?
23001                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
23002                             || uidRec.setWhitelist) {
23003                         uidRec.lastBackgroundTime = nowElapsed;
23004                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
23005                             // Note: the background settle time is in elapsed realtime, while
23006                             // the handler time base is uptime.  All this means is that we may
23007                             // stop background uids later than we had intended, but that only
23008                             // happens because the device was sleeping so we are okay anyway.
23009                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23010                                     mConstants.BACKGROUND_SETTLE_TIME);
23011                         }
23012                     }
23013                     if (uidRec.idle && !uidRec.setIdle) {
23014                         uidChange = UidRecord.CHANGE_IDLE;
23015                         if (becameIdle == null) {
23016                             becameIdle = new ArrayList<>();
23017                         }
23018                         becameIdle.add(uidRec);
23019                     }
23020                 } else {
23021                     if (uidRec.idle) {
23022                         uidChange = UidRecord.CHANGE_ACTIVE;
23023                         EventLogTags.writeAmUidActive(uidRec.uid);
23024                         uidRec.idle = false;
23025                     }
23026                     uidRec.lastBackgroundTime = 0;
23027                 }
23028                 final boolean wasCached = uidRec.setProcState
23029                         > ActivityManager.PROCESS_STATE_RECEIVER;
23030                 final boolean isCached = uidRec.curProcState
23031                         > ActivityManager.PROCESS_STATE_RECEIVER;
23032                 if (wasCached != isCached ||
23033                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
23034                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
23035                 }
23036                 uidRec.setProcState = uidRec.curProcState;
23037                 uidRec.setWhitelist = uidRec.curWhitelist;
23038                 uidRec.setIdle = uidRec.idle;
23039                 enqueueUidChangeLocked(uidRec, -1, uidChange);
23040                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
23041                 if (uidRec.foregroundServices) {
23042                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
23043                 }
23044             }
23045         }
23046         if (mLocalPowerManager != null) {
23047             mLocalPowerManager.finishUidChanges();
23048         }
23049
23050         if (becameIdle != null) {
23051             // If we have any new uids that became idle this time, we need to make sure
23052             // they aren't left with running services.
23053             for (int i = becameIdle.size() - 1; i >= 0; i--) {
23054                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
23055             }
23056         }
23057
23058         if (mProcessStats.shouldWriteNowLocked(now)) {
23059             mHandler.post(new Runnable() {
23060                 @Override public void run() {
23061                     synchronized (ActivityManagerService.this) {
23062                         mProcessStats.writeStateAsyncLocked();
23063                     }
23064                 }
23065             });
23066         }
23067
23068         if (DEBUG_OOM_ADJ) {
23069             final long duration = SystemClock.uptimeMillis() - now;
23070             if (false) {
23071                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23072                         new RuntimeException("here").fillInStackTrace());
23073             } else {
23074                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23075             }
23076         }
23077     }
23078
23079     @Override
23080     public void makePackageIdle(String packageName, int userId) {
23081         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23082                 != PackageManager.PERMISSION_GRANTED) {
23083             String msg = "Permission Denial: makePackageIdle() from pid="
23084                     + Binder.getCallingPid()
23085                     + ", uid=" + Binder.getCallingUid()
23086                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23087             Slog.w(TAG, msg);
23088             throw new SecurityException(msg);
23089         }
23090         final int callingPid = Binder.getCallingPid();
23091         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23092                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23093         long callingId = Binder.clearCallingIdentity();
23094         synchronized(this) {
23095             try {
23096                 IPackageManager pm = AppGlobals.getPackageManager();
23097                 int pkgUid = -1;
23098                 try {
23099                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23100                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23101                 } catch (RemoteException e) {
23102                 }
23103                 if (pkgUid == -1) {
23104                     throw new IllegalArgumentException("Unknown package name " + packageName);
23105                 }
23106
23107                 if (mLocalPowerManager != null) {
23108                     mLocalPowerManager.startUidChanges();
23109                 }
23110                 final int appId = UserHandle.getAppId(pkgUid);
23111                 final int N = mActiveUids.size();
23112                 for (int i=N-1; i>=0; i--) {
23113                     final UidRecord uidRec = mActiveUids.valueAt(i);
23114                     final long bgTime = uidRec.lastBackgroundTime;
23115                     if (bgTime > 0 && !uidRec.idle) {
23116                         if (UserHandle.getAppId(uidRec.uid) == appId) {
23117                             if (userId == UserHandle.USER_ALL ||
23118                                     userId == UserHandle.getUserId(uidRec.uid)) {
23119                                 EventLogTags.writeAmUidIdle(uidRec.uid);
23120                                 uidRec.idle = true;
23121                                 uidRec.setIdle = true;
23122                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23123                                         + " from package " + packageName + " user " + userId);
23124                                 doStopUidLocked(uidRec.uid, uidRec);
23125                             }
23126                         }
23127                     }
23128                 }
23129             } finally {
23130                 if (mLocalPowerManager != null) {
23131                     mLocalPowerManager.finishUidChanges();
23132                 }
23133                 Binder.restoreCallingIdentity(callingId);
23134             }
23135         }
23136     }
23137
23138     final void idleUids() {
23139         synchronized (this) {
23140             final int N = mActiveUids.size();
23141             if (N <= 0) {
23142                 return;
23143             }
23144             final long nowElapsed = SystemClock.elapsedRealtime();
23145             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23146             long nextTime = 0;
23147             if (mLocalPowerManager != null) {
23148                 mLocalPowerManager.startUidChanges();
23149             }
23150             for (int i=N-1; i>=0; i--) {
23151                 final UidRecord uidRec = mActiveUids.valueAt(i);
23152                 final long bgTime = uidRec.lastBackgroundTime;
23153                 if (bgTime > 0 && !uidRec.idle) {
23154                     if (bgTime <= maxBgTime) {
23155                         EventLogTags.writeAmUidIdle(uidRec.uid);
23156                         uidRec.idle = true;
23157                         uidRec.setIdle = true;
23158                         doStopUidLocked(uidRec.uid, uidRec);
23159                     } else {
23160                         if (nextTime == 0 || nextTime > bgTime) {
23161                             nextTime = bgTime;
23162                         }
23163                     }
23164                 }
23165             }
23166             if (mLocalPowerManager != null) {
23167                 mLocalPowerManager.finishUidChanges();
23168             }
23169             if (nextTime > 0) {
23170                 mHandler.removeMessages(IDLE_UIDS_MSG);
23171                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23172                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23173             }
23174         }
23175     }
23176
23177     /**
23178      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23179      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23180      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23181      */
23182     @VisibleForTesting
23183     @GuardedBy("this")
23184     void incrementProcStateSeqAndNotifyAppsLocked() {
23185         if (mWaitForNetworkTimeoutMs <= 0) {
23186             return;
23187         }
23188         // Used for identifying which uids need to block for network.
23189         ArrayList<Integer> blockingUids = null;
23190         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23191             final UidRecord uidRec = mActiveUids.valueAt(i);
23192             // If the network is not restricted for uid, then nothing to do here.
23193             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23194                 continue;
23195             }
23196             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23197                 continue;
23198             }
23199             // If process state is not changed, then there's nothing to do.
23200             if (uidRec.setProcState == uidRec.curProcState) {
23201                 continue;
23202             }
23203             final int blockState = getBlockStateForUid(uidRec);
23204             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23205             // there's nothing the app needs to do in this scenario.
23206             if (blockState == NETWORK_STATE_NO_CHANGE) {
23207                 continue;
23208             }
23209             synchronized (uidRec.networkStateLock) {
23210                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23211                 if (blockState == NETWORK_STATE_BLOCK) {
23212                     if (blockingUids == null) {
23213                         blockingUids = new ArrayList<>();
23214                     }
23215                     blockingUids.add(uidRec.uid);
23216                 } else {
23217                     if (DEBUG_NETWORK) {
23218                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23219                                 + " threads for uid: " + uidRec);
23220                     }
23221                     if (uidRec.waitingForNetwork) {
23222                         uidRec.networkStateLock.notifyAll();
23223                     }
23224                 }
23225             }
23226         }
23227
23228         // There are no uids that need to block, so nothing more to do.
23229         if (blockingUids == null) {
23230             return;
23231         }
23232
23233         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23234             final ProcessRecord app = mLruProcesses.get(i);
23235             if (!blockingUids.contains(app.uid)) {
23236                 continue;
23237             }
23238             if (!app.killedByAm && app.thread != null) {
23239                 final UidRecord uidRec = mActiveUids.get(app.uid);
23240                 try {
23241                     if (DEBUG_NETWORK) {
23242                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23243                                 + uidRec);
23244                     }
23245                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23246                 } catch (RemoteException ignored) {
23247                 }
23248             }
23249         }
23250     }
23251
23252     /**
23253      * Checks if the uid is coming from background to foreground or vice versa and returns
23254      * appropriate block state based on this.
23255      *
23256      * @return blockState based on whether the uid is coming from background to foreground or
23257      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23258      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23259      *         {@link #NETWORK_STATE_NO_CHANGE}.
23260      */
23261     @VisibleForTesting
23262     int getBlockStateForUid(UidRecord uidRec) {
23263         // Denotes whether uid's process state is currently allowed network access.
23264         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23265                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23266         // Denotes whether uid's process state was previously allowed network access.
23267         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23268                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23269
23270         // When the uid is coming to foreground, AMS should inform the app thread that it should
23271         // block for the network rules to get updated before launching an activity.
23272         if (!wasAllowed && isAllowed) {
23273             return NETWORK_STATE_BLOCK;
23274         }
23275         // When the uid is going to background, AMS should inform the app thread that if an
23276         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23277         if (wasAllowed && !isAllowed) {
23278             return NETWORK_STATE_UNBLOCK;
23279         }
23280         return NETWORK_STATE_NO_CHANGE;
23281     }
23282
23283     final void runInBackgroundDisabled(int uid) {
23284         synchronized (this) {
23285             UidRecord uidRec = mActiveUids.get(uid);
23286             if (uidRec != null) {
23287                 // This uid is actually running...  should it be considered background now?
23288                 if (uidRec.idle) {
23289                     doStopUidLocked(uidRec.uid, uidRec);
23290                 }
23291             } else {
23292                 // This uid isn't actually running...  still send a report about it being "stopped".
23293                 doStopUidLocked(uid, null);
23294             }
23295         }
23296     }
23297
23298     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23299         mServices.stopInBackgroundLocked(uid);
23300         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23301     }
23302
23303     /**
23304      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23305      */
23306     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23307             long duration, String tag) {
23308         if (DEBUG_WHITELISTS) {
23309             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23310                     + targetUid + ", " + duration + ")");
23311         }
23312
23313         synchronized (mPidsSelfLocked) {
23314             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23315             if (pr == null) {
23316                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23317                         + callerPid);
23318                 return;
23319             }
23320             if (!pr.whitelistManager) {
23321                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23322                         != PackageManager.PERMISSION_GRANTED) {
23323                     if (DEBUG_WHITELISTS) {
23324                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23325                                 + ": pid " + callerPid + " is not allowed");
23326                     }
23327                     return;
23328                 }
23329             }
23330         }
23331
23332         tempWhitelistUidLocked(targetUid, duration, tag);
23333     }
23334
23335     /**
23336      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23337      */
23338     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23339         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23340         setUidTempWhitelistStateLocked(targetUid, true);
23341         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23342     }
23343
23344     void pushTempWhitelist() {
23345         final int N;
23346         final PendingTempWhitelist[] list;
23347
23348         // First copy out the pending changes...  we need to leave them in the map for now,
23349         // in case someone needs to check what is coming up while we don't have the lock held.
23350         synchronized(this) {
23351             N = mPendingTempWhitelist.size();
23352             list = new PendingTempWhitelist[N];
23353             for (int i = 0; i < N; i++) {
23354                 list[i] = mPendingTempWhitelist.valueAt(i);
23355             }
23356         }
23357
23358         // Now safely dispatch changes to device idle controller.
23359         for (int i = 0; i < N; i++) {
23360             PendingTempWhitelist ptw = list[i];
23361             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23362                     ptw.duration, true, ptw.tag);
23363         }
23364
23365         // And now we can safely remove them from the map.
23366         synchronized(this) {
23367             for (int i = 0; i < N; i++) {
23368                 PendingTempWhitelist ptw = list[i];
23369                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23370                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23371                     mPendingTempWhitelist.removeAt(index);
23372                 }
23373             }
23374         }
23375     }
23376
23377     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23378         boolean changed = false;
23379         for (int i=mActiveUids.size()-1; i>=0; i--) {
23380             final UidRecord uidRec = mActiveUids.valueAt(i);
23381             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23382                 uidRec.curWhitelist = onWhitelist;
23383                 changed = true;
23384             }
23385         }
23386         if (changed) {
23387             updateOomAdjLocked();
23388         }
23389     }
23390
23391     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23392         boolean changed = false;
23393         final UidRecord uidRec = mActiveUids.get(uid);
23394         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23395             uidRec.curWhitelist = onWhitelist;
23396             updateOomAdjLocked();
23397         }
23398     }
23399
23400     final void trimApplications() {
23401         synchronized (this) {
23402             int i;
23403
23404             // First remove any unused application processes whose package
23405             // has been removed.
23406             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23407                 final ProcessRecord app = mRemovedProcesses.get(i);
23408                 if (app.activities.size() == 0
23409                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23410                     Slog.i(
23411                         TAG, "Exiting empty application process "
23412                         + app.toShortString() + " ("
23413                         + (app.thread != null ? app.thread.asBinder() : null)
23414                         + ")\n");
23415                     if (app.pid > 0 && app.pid != MY_PID) {
23416                         app.kill("empty", false);
23417                     } else {
23418                         try {
23419                             app.thread.scheduleExit();
23420                         } catch (Exception e) {
23421                             // Ignore exceptions.
23422                         }
23423                     }
23424                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23425                     mRemovedProcesses.remove(i);
23426
23427                     if (app.persistent) {
23428                         addAppLocked(app.info, null, false, null /* ABI override */);
23429                     }
23430                 }
23431             }
23432
23433             // Now update the oom adj for all processes.
23434             updateOomAdjLocked();
23435         }
23436     }
23437
23438     /** This method sends the specified signal to each of the persistent apps */
23439     public void signalPersistentProcesses(int sig) throws RemoteException {
23440         if (sig != SIGNAL_USR1) {
23441             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23442         }
23443
23444         synchronized (this) {
23445             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23446                     != PackageManager.PERMISSION_GRANTED) {
23447                 throw new SecurityException("Requires permission "
23448                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23449             }
23450
23451             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23452                 ProcessRecord r = mLruProcesses.get(i);
23453                 if (r.thread != null && r.persistent) {
23454                     sendSignal(r.pid, sig);
23455                 }
23456             }
23457         }
23458     }
23459
23460     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23461         if (proc == null || proc == mProfileProc) {
23462             proc = mProfileProc;
23463             profileType = mProfileType;
23464             clearProfilerLocked();
23465         }
23466         if (proc == null) {
23467             return;
23468         }
23469         try {
23470             proc.thread.profilerControl(false, null, profileType);
23471         } catch (RemoteException e) {
23472             throw new IllegalStateException("Process disappeared");
23473         }
23474     }
23475
23476     private void clearProfilerLocked() {
23477         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23478             try {
23479                 mProfilerInfo.profileFd.close();
23480             } catch (IOException e) {
23481             }
23482         }
23483         mProfileApp = null;
23484         mProfileProc = null;
23485         mProfilerInfo = null;
23486     }
23487
23488     public boolean profileControl(String process, int userId, boolean start,
23489             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23490
23491         try {
23492             synchronized (this) {
23493                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23494                 // its own permission.
23495                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23496                         != PackageManager.PERMISSION_GRANTED) {
23497                     throw new SecurityException("Requires permission "
23498                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23499                 }
23500
23501                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23502                     throw new IllegalArgumentException("null profile info or fd");
23503                 }
23504
23505                 ProcessRecord proc = null;
23506                 if (process != null) {
23507                     proc = findProcessLocked(process, userId, "profileControl");
23508                 }
23509
23510                 if (start && (proc == null || proc.thread == null)) {
23511                     throw new IllegalArgumentException("Unknown process: " + process);
23512                 }
23513
23514                 if (start) {
23515                     stopProfilerLocked(null, 0);
23516                     setProfileApp(proc.info, proc.processName, profilerInfo);
23517                     mProfileProc = proc;
23518                     mProfileType = profileType;
23519                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23520                     try {
23521                         fd = fd.dup();
23522                     } catch (IOException e) {
23523                         fd = null;
23524                     }
23525                     profilerInfo.profileFd = fd;
23526                     proc.thread.profilerControl(start, profilerInfo, profileType);
23527                     fd = null;
23528                     try {
23529                         mProfilerInfo.profileFd.close();
23530                     } catch (IOException e) {
23531                     }
23532                     mProfilerInfo.profileFd = null;
23533                 } else {
23534                     stopProfilerLocked(proc, profileType);
23535                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23536                         try {
23537                             profilerInfo.profileFd.close();
23538                         } catch (IOException e) {
23539                         }
23540                     }
23541                 }
23542
23543                 return true;
23544             }
23545         } catch (RemoteException e) {
23546             throw new IllegalStateException("Process disappeared");
23547         } finally {
23548             if (profilerInfo != null && profilerInfo.profileFd != null) {
23549                 try {
23550                     profilerInfo.profileFd.close();
23551                 } catch (IOException e) {
23552                 }
23553             }
23554         }
23555     }
23556
23557     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23558         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23559                 userId, true, ALLOW_FULL_ONLY, callName, null);
23560         ProcessRecord proc = null;
23561         try {
23562             int pid = Integer.parseInt(process);
23563             synchronized (mPidsSelfLocked) {
23564                 proc = mPidsSelfLocked.get(pid);
23565             }
23566         } catch (NumberFormatException e) {
23567         }
23568
23569         if (proc == null) {
23570             ArrayMap<String, SparseArray<ProcessRecord>> all
23571                     = mProcessNames.getMap();
23572             SparseArray<ProcessRecord> procs = all.get(process);
23573             if (procs != null && procs.size() > 0) {
23574                 proc = procs.valueAt(0);
23575                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23576                     for (int i=1; i<procs.size(); i++) {
23577                         ProcessRecord thisProc = procs.valueAt(i);
23578                         if (thisProc.userId == userId) {
23579                             proc = thisProc;
23580                             break;
23581                         }
23582                     }
23583                 }
23584             }
23585         }
23586
23587         return proc;
23588     }
23589
23590     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23591             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23592
23593         try {
23594             synchronized (this) {
23595                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23596                 // its own permission (same as profileControl).
23597                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23598                         != PackageManager.PERMISSION_GRANTED) {
23599                     throw new SecurityException("Requires permission "
23600                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23601                 }
23602
23603                 if (fd == null) {
23604                     throw new IllegalArgumentException("null fd");
23605                 }
23606
23607                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23608                 if (proc == null || proc.thread == null) {
23609                     throw new IllegalArgumentException("Unknown process: " + process);
23610                 }
23611
23612                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23613                 if (!isDebuggable) {
23614                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23615                         throw new SecurityException("Process not debuggable: " + proc);
23616                     }
23617                 }
23618
23619                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23620                 fd = null;
23621                 return true;
23622             }
23623         } catch (RemoteException e) {
23624             throw new IllegalStateException("Process disappeared");
23625         } finally {
23626             if (fd != null) {
23627                 try {
23628                     fd.close();
23629                 } catch (IOException e) {
23630                 }
23631             }
23632         }
23633     }
23634
23635     @Override
23636     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23637             String reportPackage) {
23638         if (processName != null) {
23639             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23640                     "setDumpHeapDebugLimit()");
23641         } else {
23642             synchronized (mPidsSelfLocked) {
23643                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23644                 if (proc == null) {
23645                     throw new SecurityException("No process found for calling pid "
23646                             + Binder.getCallingPid());
23647                 }
23648                 if (!Build.IS_DEBUGGABLE
23649                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23650                     throw new SecurityException("Not running a debuggable build");
23651                 }
23652                 processName = proc.processName;
23653                 uid = proc.uid;
23654                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23655                     throw new SecurityException("Package " + reportPackage + " is not running in "
23656                             + proc);
23657                 }
23658             }
23659         }
23660         synchronized (this) {
23661             if (maxMemSize > 0) {
23662                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23663             } else {
23664                 if (uid != 0) {
23665                     mMemWatchProcesses.remove(processName, uid);
23666                 } else {
23667                     mMemWatchProcesses.getMap().remove(processName);
23668                 }
23669             }
23670         }
23671     }
23672
23673     @Override
23674     public void dumpHeapFinished(String path) {
23675         synchronized (this) {
23676             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23677                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23678                         + " does not match last pid " + mMemWatchDumpPid);
23679                 return;
23680             }
23681             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23682                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23683                         + " does not match last path " + mMemWatchDumpFile);
23684                 return;
23685             }
23686             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23687             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23688
23689             // Forced gc to clean up the remnant hprof fd.
23690             Runtime.getRuntime().gc();
23691         }
23692     }
23693
23694     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23695     public void monitor() {
23696         synchronized (this) { }
23697     }
23698
23699     void onCoreSettingsChange(Bundle settings) {
23700         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23701             ProcessRecord processRecord = mLruProcesses.get(i);
23702             try {
23703                 if (processRecord.thread != null) {
23704                     processRecord.thread.setCoreSettings(settings);
23705                 }
23706             } catch (RemoteException re) {
23707                 /* ignore */
23708             }
23709         }
23710     }
23711
23712     // Multi-user methods
23713
23714     /**
23715      * Start user, if its not already running, but don't bring it to foreground.
23716      */
23717     @Override
23718     public boolean startUserInBackground(final int userId) {
23719         return mUserController.startUser(userId, /* foreground */ false);
23720     }
23721
23722     @Override
23723     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23724         return mUserController.unlockUser(userId, token, secret, listener);
23725     }
23726
23727     @Override
23728     public boolean switchUser(final int targetUserId) {
23729         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23730         int currentUserId;
23731         UserInfo targetUserInfo;
23732         synchronized (this) {
23733             currentUserId = mUserController.getCurrentUserIdLocked();
23734             targetUserInfo = mUserController.getUserInfo(targetUserId);
23735             if (targetUserId == currentUserId) {
23736                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23737                 return true;
23738             }
23739             if (targetUserInfo == null) {
23740                 Slog.w(TAG, "No user info for user #" + targetUserId);
23741                 return false;
23742             }
23743             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23744                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23745                         + " when device is in demo mode");
23746                 return false;
23747             }
23748             if (!targetUserInfo.supportsSwitchTo()) {
23749                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23750                 return false;
23751             }
23752             if (targetUserInfo.isManagedProfile()) {
23753                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23754                 return false;
23755             }
23756             mUserController.setTargetUserIdLocked(targetUserId);
23757         }
23758         if (mUserController.mUserSwitchUiEnabled) {
23759             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23760             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23761             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23762             mUiHandler.sendMessage(mHandler.obtainMessage(
23763                     START_USER_SWITCH_UI_MSG, userNames));
23764         } else {
23765             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23766             mHandler.sendMessage(mHandler.obtainMessage(
23767                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23768         }
23769         return true;
23770     }
23771
23772     void scheduleStartProfilesLocked() {
23773         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23774             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23775                     DateUtils.SECOND_IN_MILLIS);
23776         }
23777     }
23778
23779     @Override
23780     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23781         return mUserController.stopUser(userId, force, callback);
23782     }
23783
23784     @Override
23785     public UserInfo getCurrentUser() {
23786         return mUserController.getCurrentUser();
23787     }
23788
23789     String getStartedUserState(int userId) {
23790         synchronized (this) {
23791             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23792             return UserState.stateToString(userState.state);
23793         }
23794     }
23795
23796     @Override
23797     public boolean isUserRunning(int userId, int flags) {
23798         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23799                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23800                     != PackageManager.PERMISSION_GRANTED) {
23801             String msg = "Permission Denial: isUserRunning() from pid="
23802                     + Binder.getCallingPid()
23803                     + ", uid=" + Binder.getCallingUid()
23804                     + " requires " + INTERACT_ACROSS_USERS;
23805             Slog.w(TAG, msg);
23806             throw new SecurityException(msg);
23807         }
23808         synchronized (this) {
23809             return mUserController.isUserRunningLocked(userId, flags);
23810         }
23811     }
23812
23813     @Override
23814     public int[] getRunningUserIds() {
23815         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23816                 != PackageManager.PERMISSION_GRANTED) {
23817             String msg = "Permission Denial: isUserRunning() from pid="
23818                     + Binder.getCallingPid()
23819                     + ", uid=" + Binder.getCallingUid()
23820                     + " requires " + INTERACT_ACROSS_USERS;
23821             Slog.w(TAG, msg);
23822             throw new SecurityException(msg);
23823         }
23824         synchronized (this) {
23825             return mUserController.getStartedUserArrayLocked();
23826         }
23827     }
23828
23829     @Override
23830     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23831         mUserController.registerUserSwitchObserver(observer, name);
23832     }
23833
23834     @Override
23835     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23836         mUserController.unregisterUserSwitchObserver(observer);
23837     }
23838
23839     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23840         if (info == null) return null;
23841         ApplicationInfo newInfo = new ApplicationInfo(info);
23842         newInfo.initForUser(userId);
23843         return newInfo;
23844     }
23845
23846     public boolean isUserStopped(int userId) {
23847         synchronized (this) {
23848             return mUserController.getStartedUserStateLocked(userId) == null;
23849         }
23850     }
23851
23852     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23853         if (aInfo == null
23854                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23855             return aInfo;
23856         }
23857
23858         ActivityInfo info = new ActivityInfo(aInfo);
23859         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23860         return info;
23861     }
23862
23863     private boolean processSanityChecksLocked(ProcessRecord process) {
23864         if (process == null || process.thread == null) {
23865             return false;
23866         }
23867
23868         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23869         if (!isDebuggable) {
23870             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23871                 return false;
23872             }
23873         }
23874
23875         return true;
23876     }
23877
23878     public boolean startBinderTracking() throws RemoteException {
23879         synchronized (this) {
23880             mBinderTransactionTrackingEnabled = true;
23881             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23882             // permission (same as profileControl).
23883             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23884                     != PackageManager.PERMISSION_GRANTED) {
23885                 throw new SecurityException("Requires permission "
23886                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23887             }
23888
23889             for (int i = 0; i < mLruProcesses.size(); i++) {
23890                 ProcessRecord process = mLruProcesses.get(i);
23891                 if (!processSanityChecksLocked(process)) {
23892                     continue;
23893                 }
23894                 try {
23895                     process.thread.startBinderTracking();
23896                 } catch (RemoteException e) {
23897                     Log.v(TAG, "Process disappared");
23898                 }
23899             }
23900             return true;
23901         }
23902     }
23903
23904     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23905         try {
23906             synchronized (this) {
23907                 mBinderTransactionTrackingEnabled = false;
23908                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23909                 // permission (same as profileControl).
23910                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23911                         != PackageManager.PERMISSION_GRANTED) {
23912                     throw new SecurityException("Requires permission "
23913                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23914                 }
23915
23916                 if (fd == null) {
23917                     throw new IllegalArgumentException("null fd");
23918                 }
23919
23920                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23921                 pw.println("Binder transaction traces for all processes.\n");
23922                 for (ProcessRecord process : mLruProcesses) {
23923                     if (!processSanityChecksLocked(process)) {
23924                         continue;
23925                     }
23926
23927                     pw.println("Traces for process: " + process.processName);
23928                     pw.flush();
23929                     try {
23930                         TransferPipe tp = new TransferPipe();
23931                         try {
23932                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23933                             tp.go(fd.getFileDescriptor());
23934                         } finally {
23935                             tp.kill();
23936                         }
23937                     } catch (IOException e) {
23938                         pw.println("Failure while dumping IPC traces from " + process +
23939                                 ".  Exception: " + e);
23940                         pw.flush();
23941                     } catch (RemoteException e) {
23942                         pw.println("Got a RemoteException while dumping IPC traces from " +
23943                                 process + ".  Exception: " + e);
23944                         pw.flush();
23945                     }
23946                 }
23947                 fd = null;
23948                 return true;
23949             }
23950         } finally {
23951             if (fd != null) {
23952                 try {
23953                     fd.close();
23954                 } catch (IOException e) {
23955                 }
23956             }
23957         }
23958     }
23959
23960     @VisibleForTesting
23961     final class LocalService extends ActivityManagerInternal {
23962         @Override
23963         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23964                 int targetUserId) {
23965             synchronized (ActivityManagerService.this) {
23966                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23967                         targetPkg, intent, null, targetUserId);
23968             }
23969         }
23970
23971         @Override
23972         public String checkContentProviderAccess(String authority, int userId) {
23973             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23974         }
23975
23976         @Override
23977         public void onWakefulnessChanged(int wakefulness) {
23978             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23979         }
23980
23981         @Override
23982         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23983                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23984             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23985                     processName, abiOverride, uid, crashHandler);
23986         }
23987
23988         @Override
23989         public SleepToken acquireSleepToken(String tag, int displayId) {
23990             Preconditions.checkNotNull(tag);
23991             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23992         }
23993
23994         @Override
23995         public ComponentName getHomeActivityForUser(int userId) {
23996             synchronized (ActivityManagerService.this) {
23997                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23998                 return homeActivity == null ? null : homeActivity.realActivity;
23999             }
24000         }
24001
24002         @Override
24003         public void onUserRemoved(int userId) {
24004             synchronized (ActivityManagerService.this) {
24005                 ActivityManagerService.this.onUserStoppedLocked(userId);
24006             }
24007             mBatteryStatsService.onUserRemoved(userId);
24008         }
24009
24010         @Override
24011         public void onLocalVoiceInteractionStarted(IBinder activity,
24012                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
24013             synchronized (ActivityManagerService.this) {
24014                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
24015                         voiceSession, voiceInteractor);
24016             }
24017         }
24018
24019         @Override
24020         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
24021             synchronized (ActivityManagerService.this) {
24022                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
24023                         reasons, timestamp);
24024             }
24025         }
24026
24027         @Override
24028         public void notifyAppTransitionFinished() {
24029             synchronized (ActivityManagerService.this) {
24030                 mStackSupervisor.notifyAppTransitionDone();
24031             }
24032         }
24033
24034         @Override
24035         public void notifyAppTransitionCancelled() {
24036             synchronized (ActivityManagerService.this) {
24037                 mStackSupervisor.notifyAppTransitionDone();
24038             }
24039         }
24040
24041         @Override
24042         public List<IBinder> getTopVisibleActivities() {
24043             synchronized (ActivityManagerService.this) {
24044                 return mStackSupervisor.getTopVisibleActivities();
24045             }
24046         }
24047
24048         @Override
24049         public void notifyDockedStackMinimizedChanged(boolean minimized) {
24050             synchronized (ActivityManagerService.this) {
24051                 mStackSupervisor.setDockedStackMinimized(minimized);
24052             }
24053         }
24054
24055         @Override
24056         public void killForegroundAppsForUser(int userHandle) {
24057             synchronized (ActivityManagerService.this) {
24058                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
24059                 final int NP = mProcessNames.getMap().size();
24060                 for (int ip = 0; ip < NP; ip++) {
24061                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
24062                     final int NA = apps.size();
24063                     for (int ia = 0; ia < NA; ia++) {
24064                         final ProcessRecord app = apps.valueAt(ia);
24065                         if (app.persistent) {
24066                             // We don't kill persistent processes.
24067                             continue;
24068                         }
24069                         if (app.removed) {
24070                             procs.add(app);
24071                         } else if (app.userId == userHandle && app.foregroundActivities) {
24072                             app.removed = true;
24073                             procs.add(app);
24074                         }
24075                     }
24076                 }
24077
24078                 final int N = procs.size();
24079                 for (int i = 0; i < N; i++) {
24080                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
24081                 }
24082             }
24083         }
24084
24085         @Override
24086         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24087                 long duration) {
24088             if (!(target instanceof PendingIntentRecord)) {
24089                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24090                 return;
24091             }
24092             synchronized (ActivityManagerService.this) {
24093                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24094             }
24095         }
24096
24097         @Override
24098         public void setDeviceIdleWhitelist(int[] appids) {
24099             synchronized (ActivityManagerService.this) {
24100                 mDeviceIdleWhitelist = appids;
24101             }
24102         }
24103
24104         @Override
24105         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24106             synchronized (ActivityManagerService.this) {
24107                 mDeviceIdleTempWhitelist = appids;
24108                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24109             }
24110         }
24111
24112         @Override
24113         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24114                 int userId) {
24115             Preconditions.checkNotNull(values, "Configuration must not be null");
24116             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24117             synchronized (ActivityManagerService.this) {
24118                 updateConfigurationLocked(values, null, false, true, userId,
24119                         false /* deferResume */);
24120             }
24121         }
24122
24123         @Override
24124         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24125                 Bundle bOptions) {
24126             Preconditions.checkNotNull(intents, "intents");
24127             final String[] resolvedTypes = new String[intents.length];
24128             for (int i = 0; i < intents.length; i++) {
24129                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24130             }
24131
24132             // UID of the package on user userId.
24133             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24134             // packageUid may not be initialized.
24135             int packageUid = 0;
24136             try {
24137                 packageUid = AppGlobals.getPackageManager().getPackageUid(
24138                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24139             } catch (RemoteException e) {
24140                 // Shouldn't happen.
24141             }
24142
24143             synchronized (ActivityManagerService.this) {
24144                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24145                         /*resultTo*/ null, bOptions, userId);
24146             }
24147         }
24148
24149         @Override
24150         public int getUidProcessState(int uid) {
24151             return getUidState(uid);
24152         }
24153
24154         @Override
24155         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24156             synchronized (ActivityManagerService.this) {
24157
24158                 // We might change the visibilities here, so prepare an empty app transition which
24159                 // might be overridden later if we actually change visibilities.
24160                 final boolean wasTransitionSet =
24161                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24162                 if (!wasTransitionSet) {
24163                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24164                             false /* alwaysKeepCurrent */);
24165                 }
24166                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24167
24168                 // If there was a transition set already we don't want to interfere with it as we
24169                 // might be starting it too early.
24170                 if (!wasTransitionSet) {
24171                     mWindowManager.executeAppTransition();
24172                 }
24173             }
24174             if (callback != null) {
24175                 callback.run();
24176             }
24177         }
24178
24179         @Override
24180         public boolean isSystemReady() {
24181             // no need to synchronize(this) just to read & return the value
24182             return mSystemReady;
24183         }
24184
24185         @Override
24186         public void notifyKeyguardTrustedChanged() {
24187             synchronized (ActivityManagerService.this) {
24188                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24189                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24190                 }
24191             }
24192         }
24193
24194         /**
24195          * Sets if the given pid has an overlay UI or not.
24196          *
24197          * @param pid The pid we are setting overlay UI for.
24198          * @param hasOverlayUi True if the process has overlay UI.
24199          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24200          */
24201         @Override
24202         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24203             synchronized (ActivityManagerService.this) {
24204                 final ProcessRecord pr;
24205                 synchronized (mPidsSelfLocked) {
24206                     pr = mPidsSelfLocked.get(pid);
24207                     if (pr == null) {
24208                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24209                         return;
24210                     }
24211                 }
24212                 if (pr.hasOverlayUi == hasOverlayUi) {
24213                     return;
24214                 }
24215                 pr.hasOverlayUi = hasOverlayUi;
24216                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24217                 updateOomAdjLocked(pr, true);
24218             }
24219         }
24220
24221         /**
24222          * Called after the network policy rules are updated by
24223          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24224          * and {@param procStateSeq}.
24225          */
24226         @Override
24227         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24228             if (DEBUG_NETWORK) {
24229                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24230                         + uid + " seq: " + procStateSeq);
24231             }
24232             UidRecord record;
24233             synchronized (ActivityManagerService.this) {
24234                 record = mActiveUids.get(uid);
24235                 if (record == null) {
24236                     if (DEBUG_NETWORK) {
24237                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24238                                 + " procStateSeq: " + procStateSeq);
24239                     }
24240                     return;
24241                 }
24242             }
24243             synchronized (record.networkStateLock) {
24244                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24245                     if (DEBUG_NETWORK) {
24246                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24247                                 + " been handled for uid: " + uid);
24248                     }
24249                     return;
24250                 }
24251                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24252                 if (record.curProcStateSeq > procStateSeq) {
24253                     if (DEBUG_NETWORK) {
24254                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24255                                 + ", curProcstateSeq: " + record.curProcStateSeq
24256                                 + ", procStateSeq: " + procStateSeq);
24257                     }
24258                     return;
24259                 }
24260                 if (record.waitingForNetwork) {
24261                     if (DEBUG_NETWORK) {
24262                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24263                                 + ", procStateSeq: " + procStateSeq);
24264                     }
24265                     record.networkStateLock.notifyAll();
24266                 }
24267             }
24268         }
24269
24270         /**
24271          * Called after virtual display Id is updated by
24272          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24273          * {@param vrVr2dDisplayId}.
24274          */
24275         @Override
24276         public void setVr2dDisplayId(int vr2dDisplayId) {
24277             if (DEBUG_STACK) {
24278                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24279                         vr2dDisplayId);
24280             }
24281             synchronized (ActivityManagerService.this) {
24282                 mVr2dDisplayId = vr2dDisplayId;
24283             }
24284         }
24285
24286         @Override
24287         public void saveANRState(String reason) {
24288             synchronized (ActivityManagerService.this) {
24289                 final StringWriter sw = new StringWriter();
24290                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24291                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24292                 if (reason != null) {
24293                     pw.println("  Reason: " + reason);
24294                 }
24295                 pw.println();
24296                 mActivityStarter.dump(pw, "  ", null);
24297                 pw.println();
24298                 pw.println("-------------------------------------------------------------------------------");
24299                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24300                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24301                         "" /* header */);
24302                 pw.println();
24303                 pw.close();
24304
24305                 mLastANRState = sw.toString();
24306             }
24307         }
24308
24309         @Override
24310         public void clearSavedANRState() {
24311             synchronized (ActivityManagerService.this) {
24312                 mLastANRState = null;
24313             }
24314         }
24315
24316         @Override
24317         public void setFocusedActivity(IBinder token) {
24318             synchronized (ActivityManagerService.this) {
24319                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24320                 if (r == null) {
24321                     throw new IllegalArgumentException(
24322                             "setFocusedActivity: No activity record matching token=" + token);
24323                 }
24324                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24325                         r, "setFocusedActivity")) {
24326                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
24327                 }
24328             }
24329         }
24330
24331         @Override
24332         public void registerScreenObserver(ScreenObserver observer) {
24333             mScreenObservers.add(observer);
24334         }
24335     }
24336
24337     /**
24338      * Called by app main thread to wait for the network policy rules to get updated.
24339      *
24340      * @param procStateSeq The sequence number indicating the process state change that the main
24341      *                     thread is interested in.
24342      */
24343     @Override
24344     public void waitForNetworkStateUpdate(long procStateSeq) {
24345         final int callingUid = Binder.getCallingUid();
24346         if (DEBUG_NETWORK) {
24347             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24348         }
24349         UidRecord record;
24350         synchronized (this) {
24351             record = mActiveUids.get(callingUid);
24352             if (record == null) {
24353                 return;
24354             }
24355         }
24356         synchronized (record.networkStateLock) {
24357             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24358                 if (DEBUG_NETWORK) {
24359                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24360                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24361                             + " lastProcStateSeqDispatchedToObservers: "
24362                             + record.lastDispatchedProcStateSeq);
24363                 }
24364                 return;
24365             }
24366             if (record.curProcStateSeq > procStateSeq) {
24367                 if (DEBUG_NETWORK) {
24368                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24369                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24370                             + ", procStateSeq: " + procStateSeq);
24371                 }
24372                 return;
24373             }
24374             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24375                 if (DEBUG_NETWORK) {
24376                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24377                             + procStateSeq + ", so no need to wait. Uid: "
24378                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24379                             + record.lastNetworkUpdatedProcStateSeq);
24380                 }
24381                 return;
24382             }
24383             try {
24384                 if (DEBUG_NETWORK) {
24385                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24386                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24387                 }
24388                 final long startTime = SystemClock.uptimeMillis();
24389                 record.waitingForNetwork = true;
24390                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24391                 record.waitingForNetwork = false;
24392                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24393                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24394                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24395                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24396                             + procStateSeq + " UidRec: " + record
24397                             + " validateUidRec: " + mValidateUids.get(callingUid));
24398                 }
24399             } catch (InterruptedException e) {
24400                 Thread.currentThread().interrupt();
24401             }
24402         }
24403     }
24404
24405     public void waitForBroadcastIdle(PrintWriter pw) {
24406         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24407         while (true) {
24408             boolean idle = true;
24409             synchronized (this) {
24410                 for (BroadcastQueue queue : mBroadcastQueues) {
24411                     if (!queue.isIdle()) {
24412                         final String msg = "Waiting for queue " + queue + " to become idle...";
24413                         pw.println(msg);
24414                         pw.flush();
24415                         Slog.v(TAG, msg);
24416                         idle = false;
24417                     }
24418                 }
24419             }
24420
24421             if (idle) {
24422                 final String msg = "All broadcast queues are idle!";
24423                 pw.println(msg);
24424                 pw.flush();
24425                 Slog.v(TAG, msg);
24426                 return;
24427             } else {
24428                 SystemClock.sleep(1000);
24429             }
24430         }
24431     }
24432
24433     /**
24434      * Return the user id of the last resumed activity.
24435      */
24436     @Override
24437     public @UserIdInt int getLastResumedActivityUserId() {
24438         enforceCallingPermission(
24439                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24440         synchronized (this) {
24441             if (mLastResumedActivity == null) {
24442                 return mUserController.getCurrentUserIdLocked();
24443             }
24444             return mLastResumedActivity.userId;
24445         }
24446     }
24447
24448     /**
24449      * An implementation of IAppTask, that allows an app to manage its own tasks via
24450      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24451      * only the process that calls getAppTasks() can call the AppTask methods.
24452      */
24453     class AppTaskImpl extends IAppTask.Stub {
24454         private int mTaskId;
24455         private int mCallingUid;
24456
24457         public AppTaskImpl(int taskId, int callingUid) {
24458             mTaskId = taskId;
24459             mCallingUid = callingUid;
24460         }
24461
24462         private void checkCaller() {
24463             if (mCallingUid != Binder.getCallingUid()) {
24464                 throw new SecurityException("Caller " + mCallingUid
24465                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24466             }
24467         }
24468
24469         @Override
24470         public void finishAndRemoveTask() {
24471             checkCaller();
24472
24473             synchronized (ActivityManagerService.this) {
24474                 long origId = Binder.clearCallingIdentity();
24475                 try {
24476                     // We remove the task from recents to preserve backwards
24477                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24478                             REMOVE_FROM_RECENTS)) {
24479                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24480                     }
24481                 } finally {
24482                     Binder.restoreCallingIdentity(origId);
24483                 }
24484             }
24485         }
24486
24487         @Override
24488         public ActivityManager.RecentTaskInfo getTaskInfo() {
24489             checkCaller();
24490
24491             synchronized (ActivityManagerService.this) {
24492                 long origId = Binder.clearCallingIdentity();
24493                 try {
24494                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24495                     if (tr == null) {
24496                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24497                     }
24498                     return createRecentTaskInfoFromTaskRecord(tr);
24499                 } finally {
24500                     Binder.restoreCallingIdentity(origId);
24501                 }
24502             }
24503         }
24504
24505         @Override
24506         public void moveToFront() {
24507             checkCaller();
24508             // Will bring task to front if it already has a root activity.
24509             final long origId = Binder.clearCallingIdentity();
24510             try {
24511                 synchronized (this) {
24512                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24513                 }
24514             } finally {
24515                 Binder.restoreCallingIdentity(origId);
24516             }
24517         }
24518
24519         @Override
24520         public int startActivity(IBinder whoThread, String callingPackage,
24521                 Intent intent, String resolvedType, Bundle bOptions) {
24522             checkCaller();
24523
24524             int callingUser = UserHandle.getCallingUserId();
24525             TaskRecord tr;
24526             IApplicationThread appThread;
24527             synchronized (ActivityManagerService.this) {
24528                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24529                 if (tr == null) {
24530                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24531                 }
24532                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24533                 if (appThread == null) {
24534                     throw new IllegalArgumentException("Bad app thread " + appThread);
24535                 }
24536             }
24537             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24538                     resolvedType, null, null, null, null, 0, 0, null, null,
24539                     null, bOptions, false, callingUser, tr, "AppTaskImpl");
24540         }
24541
24542         @Override
24543         public void setExcludeFromRecents(boolean exclude) {
24544             checkCaller();
24545
24546             synchronized (ActivityManagerService.this) {
24547                 long origId = Binder.clearCallingIdentity();
24548                 try {
24549                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24550                     if (tr == null) {
24551                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24552                     }
24553                     Intent intent = tr.getBaseIntent();
24554                     if (exclude) {
24555                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24556                     } else {
24557                         intent.setFlags(intent.getFlags()
24558                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24559                     }
24560                 } finally {
24561                     Binder.restoreCallingIdentity(origId);
24562                 }
24563             }
24564         }
24565     }
24566
24567     /**
24568      * Kill processes for the user with id userId and that depend on the package named packageName
24569      */
24570     @Override
24571     public void killPackageDependents(String packageName, int userId) {
24572         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24573         if (packageName == null) {
24574             throw new NullPointerException(
24575                     "Cannot kill the dependents of a package without its name.");
24576         }
24577
24578         long callingId = Binder.clearCallingIdentity();
24579         IPackageManager pm = AppGlobals.getPackageManager();
24580         int pkgUid = -1;
24581         try {
24582             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24583         } catch (RemoteException e) {
24584         }
24585         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24586             throw new IllegalArgumentException(
24587                     "Cannot kill dependents of non-existing package " + packageName);
24588         }
24589         try {
24590             synchronized(this) {
24591                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24592                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24593                         "dep: " + packageName);
24594             }
24595         } finally {
24596             Binder.restoreCallingIdentity(callingId);
24597         }
24598     }
24599
24600     @Override
24601     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24602             throws RemoteException {
24603         final long callingId = Binder.clearCallingIdentity();
24604         try {
24605             mKeyguardController.dismissKeyguard(token, callback);
24606         } finally {
24607             Binder.restoreCallingIdentity(callingId);
24608         }
24609     }
24610
24611     @Override
24612     public int restartUserInBackground(final int userId) {
24613         return mUserController.restartUser(userId, /* foreground */ false);
24614     }
24615
24616     @Override
24617     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24618         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24619                 "scheduleApplicationInfoChanged()");
24620
24621         synchronized (this) {
24622             final long origId = Binder.clearCallingIdentity();
24623             try {
24624                 updateApplicationInfoLocked(packageNames, userId);
24625             } finally {
24626                 Binder.restoreCallingIdentity(origId);
24627             }
24628         }
24629     }
24630
24631     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24632         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24633         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24634             final ProcessRecord app = mLruProcesses.get(i);
24635             if (app.thread == null) {
24636                 continue;
24637             }
24638
24639             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24640                 continue;
24641             }
24642
24643             final int packageCount = app.pkgList.size();
24644             for (int j = 0; j < packageCount; j++) {
24645                 final String packageName = app.pkgList.keyAt(j);
24646                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24647                     try {
24648                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24649                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24650                         if (ai != null) {
24651                             app.thread.scheduleApplicationInfoChanged(ai);
24652                         }
24653                     } catch (RemoteException e) {
24654                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24655                                     packageName, app));
24656                     }
24657                 }
24658             }
24659         }
24660     }
24661
24662     /**
24663      * Attach an agent to the specified process (proces name or PID)
24664      */
24665     public void attachAgent(String process, String path) {
24666         try {
24667             synchronized (this) {
24668                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24669                 if (proc == null || proc.thread == null) {
24670                     throw new IllegalArgumentException("Unknown process: " + process);
24671                 }
24672
24673                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24674                 if (!isDebuggable) {
24675                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24676                         throw new SecurityException("Process not debuggable: " + proc);
24677                     }
24678                 }
24679
24680                 proc.thread.attachAgent(path);
24681             }
24682         } catch (RemoteException e) {
24683             throw new IllegalStateException("Process disappeared");
24684         }
24685     }
24686
24687     @VisibleForTesting
24688     public static class Injector {
24689         private NetworkManagementInternal mNmi;
24690
24691         public Context getContext() {
24692             return null;
24693         }
24694
24695         public AppOpsService getAppOpsService(File file, Handler handler) {
24696             return new AppOpsService(file, handler);
24697         }
24698
24699         public Handler getUiHandler(ActivityManagerService service) {
24700             return service.new UiHandler();
24701         }
24702
24703         public boolean isNetworkRestrictedForUid(int uid) {
24704             if (ensureHasNetworkManagementInternal()) {
24705                 return mNmi.isNetworkRestrictedForUid(uid);
24706             }
24707             return false;
24708         }
24709
24710         private boolean ensureHasNetworkManagementInternal() {
24711             if (mNmi == null) {
24712                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24713             }
24714             return mNmi != null;
24715         }
24716     }
24717
24718     @Override
24719     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24720             throws RemoteException {
24721         synchronized (this) {
24722             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24723             if (r == null) {
24724                 return;
24725             }
24726             final long origId = Binder.clearCallingIdentity();
24727             try {
24728                 r.setShowWhenLocked(showWhenLocked);
24729             } finally {
24730                 Binder.restoreCallingIdentity(origId);
24731             }
24732         }
24733     }
24734
24735     @Override
24736     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24737         synchronized (this) {
24738             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24739             if (r == null) {
24740                 return;
24741             }
24742             final long origId = Binder.clearCallingIdentity();
24743             try {
24744                 r.setTurnScreenOn(turnScreenOn);
24745             } finally {
24746                 Binder.restoreCallingIdentity(origId);
24747             }
24748         }
24749     }
24750 }