OSDN Git Service

Merge tag 'android-8.1.0_r64' into oreo-x86
[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.SleepToken;
204 import android.app.ActivityOptions;
205 import android.app.ActivityThread;
206 import android.app.AlertDialog;
207 import android.app.AppGlobals;
208 import android.app.AppOpsManager;
209 import android.app.ApplicationErrorReport;
210 import android.app.ApplicationThreadConstants;
211 import android.app.BroadcastOptions;
212 import android.app.ContentProviderHolder;
213 import android.app.Dialog;
214 import android.app.IActivityController;
215 import android.app.IActivityManager;
216 import android.app.IAppTask;
217 import android.app.IApplicationThread;
218 import android.app.IInstrumentationWatcher;
219 import android.app.INotificationManager;
220 import android.app.IProcessObserver;
221 import android.app.IServiceConnection;
222 import android.app.IStopUserCallback;
223 import android.app.ITaskStackListener;
224 import android.app.IUiAutomationConnection;
225 import android.app.IUidObserver;
226 import android.app.IUserSwitchObserver;
227 import android.app.Instrumentation;
228 import android.app.Notification;
229 import android.app.NotificationManager;
230 import android.app.PendingIntent;
231 import android.app.PictureInPictureParams;
232 import android.app.ProfilerInfo;
233 import android.app.RemoteAction;
234 import android.app.WaitResult;
235 import android.app.admin.DevicePolicyManager;
236 import android.app.assist.AssistContent;
237 import android.app.assist.AssistStructure;
238 import android.app.backup.IBackupManager;
239 import android.app.usage.UsageEvents;
240 import android.app.usage.UsageStatsManagerInternal;
241 import android.appwidget.AppWidgetManager;
242 import android.content.ActivityNotFoundException;
243 import android.content.BroadcastReceiver;
244 import android.content.ClipData;
245 import android.content.ComponentCallbacks2;
246 import android.content.ComponentName;
247 import android.content.ContentProvider;
248 import android.content.ContentResolver;
249 import android.content.Context;
250 import android.content.DialogInterface;
251 import android.content.IContentProvider;
252 import android.content.IIntentReceiver;
253 import android.content.IIntentSender;
254 import android.content.Intent;
255 import android.content.IntentFilter;
256 import android.content.pm.ActivityInfo;
257 import android.content.pm.ApplicationInfo;
258 import android.content.pm.ConfigurationInfo;
259 import android.content.pm.IPackageDataObserver;
260 import android.content.pm.IPackageManager;
261 import android.content.pm.InstrumentationInfo;
262 import android.content.pm.PackageInfo;
263 import android.content.pm.PackageManager;
264 import android.content.pm.PackageManager.NameNotFoundException;
265 import android.content.pm.PackageManagerInternal;
266 import android.content.pm.ParceledListSlice;
267 import android.content.pm.PathPermission;
268 import android.content.pm.PermissionInfo;
269 import android.content.pm.ProviderInfo;
270 import android.content.pm.ResolveInfo;
271 import android.content.pm.SELinuxUtil;
272 import android.content.pm.ServiceInfo;
273 import android.content.pm.UserInfo;
274 import android.content.res.CompatibilityInfo;
275 import android.content.res.Configuration;
276 import android.content.res.Resources;
277 import android.database.ContentObserver;
278 import android.graphics.Bitmap;
279 import android.graphics.Point;
280 import android.graphics.Rect;
281 import android.location.LocationManager;
282 import android.media.audiofx.AudioEffect;
283 import android.metrics.LogMaker;
284 import android.net.Proxy;
285 import android.net.ProxyInfo;
286 import android.net.Uri;
287 import android.os.BatteryStats;
288 import android.os.Binder;
289 import android.os.Build;
290 import android.os.Bundle;
291 import android.os.Debug;
292 import android.os.DropBoxManager;
293 import android.os.Environment;
294 import android.os.FactoryTest;
295 import android.os.FileObserver;
296 import android.os.FileUtils;
297 import android.os.Handler;
298 import android.os.IBinder;
299 import android.os.IDeviceIdentifiersPolicyService;
300 import android.os.IPermissionController;
301 import android.os.IProcessInfoService;
302 import android.os.IProgressListener;
303 import android.os.LocaleList;
304 import android.os.Looper;
305 import android.os.Message;
306 import android.os.Parcel;
307 import android.os.ParcelFileDescriptor;
308 import android.os.PersistableBundle;
309 import android.os.PowerManager;
310 import android.os.PowerManagerInternal;
311 import android.os.Process;
312 import android.os.RemoteCallbackList;
313 import android.os.RemoteException;
314 import android.os.ResultReceiver;
315 import android.os.ServiceManager;
316 import android.os.ShellCallback;
317 import android.os.StrictMode;
318 import android.os.SystemClock;
319 import android.os.SystemProperties;
320 import android.os.Trace;
321 import android.os.TransactionTooLargeException;
322 import android.os.UpdateLock;
323 import android.os.UserHandle;
324 import android.os.UserManager;
325 import android.os.WorkSource;
326 import android.os.storage.IStorageManager;
327 import android.os.storage.StorageManager;
328 import android.os.storage.StorageManagerInternal;
329 import android.provider.Downloads;
330 import android.provider.Settings;
331 import android.service.voice.IVoiceInteractionSession;
332 import android.service.voice.VoiceInteractionManagerInternal;
333 import android.service.voice.VoiceInteractionSession;
334 import android.telecom.TelecomManager;
335 import android.text.TextUtils;
336 import android.text.format.DateUtils;
337 import android.text.format.Time;
338 import android.text.style.SuggestionSpan;
339 import android.util.ArrayMap;
340 import android.util.ArraySet;
341 import android.util.AtomicFile;
342 import android.util.TimingsTraceLog;
343 import android.util.DebugUtils;
344 import android.util.DisplayMetrics;
345 import android.util.EventLog;
346 import android.util.Log;
347 import android.util.Pair;
348 import android.util.PrintWriterPrinter;
349 import android.util.Slog;
350 import android.util.SparseArray;
351 import android.util.SparseIntArray;
352 import android.util.TimeUtils;
353 import android.util.Xml;
354 import android.view.Gravity;
355 import android.view.LayoutInflater;
356 import android.view.View;
357 import android.view.WindowManager;
358
359 import com.android.server.job.JobSchedulerInternal;
360 import com.google.android.collect.Lists;
361 import com.google.android.collect.Maps;
362
363 import com.android.internal.R;
364 import com.android.internal.annotations.GuardedBy;
365 import com.android.internal.annotations.VisibleForTesting;
366 import com.android.internal.app.AssistUtils;
367 import com.android.internal.app.DumpHeapActivity;
368 import com.android.internal.app.IAppOpsCallback;
369 import com.android.internal.app.IAppOpsService;
370 import com.android.internal.app.IVoiceInteractor;
371 import com.android.internal.app.ProcessMap;
372 import com.android.internal.app.SystemUserHomeActivity;
373 import com.android.internal.app.procstats.ProcessStats;
374 import com.android.internal.logging.MetricsLogger;
375 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
376 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
377 import com.android.internal.notification.SystemNotificationChannels;
378 import com.android.internal.os.BackgroundThread;
379 import com.android.internal.os.BatteryStatsImpl;
380 import com.android.internal.os.IResultReceiver;
381 import com.android.internal.os.ProcessCpuTracker;
382 import com.android.internal.os.TransferPipe;
383 import com.android.internal.os.Zygote;
384 import com.android.internal.policy.IKeyguardDismissCallback;
385 import com.android.internal.telephony.TelephonyIntents;
386 import com.android.internal.util.ArrayUtils;
387 import com.android.internal.util.DumpUtils;
388 import com.android.internal.util.FastPrintWriter;
389 import com.android.internal.util.FastXmlSerializer;
390 import com.android.internal.util.MemInfoReader;
391 import com.android.internal.util.Preconditions;
392 import com.android.server.AppOpsService;
393 import com.android.server.AttributeCache;
394 import com.android.server.DeviceIdleController;
395 import com.android.server.IntentResolver;
396 import com.android.server.LocalServices;
397 import com.android.server.LockGuard;
398 import com.android.server.NetworkManagementInternal;
399 import com.android.server.RescueParty;
400 import com.android.server.ServiceThread;
401 import com.android.server.SystemConfig;
402 import com.android.server.SystemService;
403 import com.android.server.SystemServiceManager;
404 import com.android.server.ThreadPriorityBooster;
405 import com.android.server.Watchdog;
406 import com.android.server.am.ActivityStack.ActivityState;
407 import com.android.server.firewall.IntentFirewall;
408 import com.android.server.pm.Installer;
409 import com.android.server.pm.Installer.InstallerException;
410 import com.android.server.statusbar.StatusBarManagerInternal;
411 import com.android.server.vr.VrManagerInternal;
412 import com.android.server.wm.PinnedStackWindowController;
413 import com.android.server.wm.WindowManagerService;
414
415 import java.text.SimpleDateFormat;
416 import org.xmlpull.v1.XmlPullParser;
417 import org.xmlpull.v1.XmlPullParserException;
418 import org.xmlpull.v1.XmlSerializer;
419
420 import java.io.File;
421 import java.io.FileDescriptor;
422 import java.io.FileInputStream;
423 import java.io.FileNotFoundException;
424 import java.io.FileOutputStream;
425 import java.io.IOException;
426 import java.io.InputStreamReader;
427 import java.io.PrintWriter;
428 import java.io.StringWriter;
429 import java.io.UnsupportedEncodingException;
430 import java.lang.ref.WeakReference;
431 import java.nio.charset.StandardCharsets;
432 import java.text.DateFormat;
433 import java.util.ArrayList;
434 import java.util.Arrays;
435 import java.util.Collections;
436 import java.util.Comparator;
437 import java.util.Date;
438 import java.util.HashMap;
439 import java.util.HashSet;
440 import java.util.Iterator;
441 import java.util.List;
442 import java.util.Locale;
443 import java.util.Map;
444 import java.util.Objects;
445 import java.util.Set;
446 import java.util.concurrent.CountDownLatch;
447 import java.util.concurrent.atomic.AtomicBoolean;
448 import java.util.concurrent.atomic.AtomicLong;
449
450 import dalvik.system.VMRuntime;
451 import libcore.io.IoUtils;
452 import libcore.util.EmptyArray;
453
454 public class ActivityManagerService extends IActivityManager.Stub
455         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
456
457     /**
458      * Priority we boost main thread and RT of top app to.
459      */
460     public static final int TOP_APP_PRIORITY_BOOST = -10;
461
462     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
463     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
464     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
465     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
466     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
467     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
468     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
469     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
470     private static final String TAG_LRU = TAG + POSTFIX_LRU;
471     private static final String TAG_MU = TAG + POSTFIX_MU;
472     private static final String TAG_NETWORK = TAG + POSTFIX_NETWORK;
473     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
474     private static final String TAG_POWER = TAG + POSTFIX_POWER;
475     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
476     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
477     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
478     private static final String TAG_PSS = TAG + POSTFIX_PSS;
479     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
480     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
481     private static final String TAG_STACK = TAG + POSTFIX_STACK;
482     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
483     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
484     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
485     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
486
487     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
488     // here so that while the job scheduler can depend on AMS, the other way around
489     // need not be the case.
490     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
491
492     /** Control over CPU and battery monitoring */
493     // write battery stats every 30 minutes.
494     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
495     static final boolean MONITOR_CPU_USAGE = true;
496     // don't sample cpu less than every 5 seconds.
497     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
498     // wait possibly forever for next cpu sample.
499     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
500     static final boolean MONITOR_THREAD_CPU_USAGE = false;
501
502     // The flags that are set for all calls we make to the package manager.
503     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
504
505     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
506
507     // Amount of time after a call to stopAppSwitches() during which we will
508     // prevent further untrusted switches from happening.
509     static final long APP_SWITCH_DELAY_TIME = 5*1000;
510
511     // How long we wait for a launched process to attach to the activity manager
512     // before we decide it's never going to come up for real.
513     static final int PROC_START_TIMEOUT = 10*1000;
514     // How long we wait for an attached process to publish its content providers
515     // before we decide it must be hung.
516     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
517
518     // How long we wait for a launched process to attach to the activity manager
519     // before we decide it's never going to come up for real, when the process was
520     // started with a wrapper for instrumentation (such as Valgrind) because it
521     // could take much longer than usual.
522     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
523
524     // How long we allow a receiver to run before giving up on it.
525     static final int BROADCAST_FG_TIMEOUT = 10*1000;
526     static final int BROADCAST_BG_TIMEOUT = 60*1000;
527
528     // How long we wait until we timeout on key dispatching.
529     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
530
531     // How long we wait until we timeout on key dispatching during instrumentation.
532     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
533
534     // How long to wait in getAssistContextExtras for the activity and foreground services
535     // to respond with the result.
536     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
537
538     // How long top wait when going through the modern assist (which doesn't need to block
539     // on getting this result before starting to launch its UI).
540     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
541
542     // How long to wait in getAutofillAssistStructure() for the activity to respond with the result.
543     static final int PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT = 2000;
544
545     // Maximum number of persisted Uri grants a package is allowed
546     static final int MAX_PERSISTED_URI_GRANTS = 128;
547
548     static final int MY_PID = myPid();
549
550     static final String[] EMPTY_STRING_ARRAY = new String[0];
551
552     // How many bytes to write into the dropbox log before truncating
553     static final int DROPBOX_MAX_SIZE = 192 * 1024;
554     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
555     // as one line, but close enough for now.
556     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
557
558     // Access modes for handleIncomingUser.
559     static final int ALLOW_NON_FULL = 0;
560     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
561     static final int ALLOW_FULL_ONLY = 2;
562
563     // Necessary ApplicationInfo flags to mark an app as persistent
564     private static final int PERSISTENT_MASK =
565             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
566
567     // Intent sent when remote bugreport collection has been completed
568     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
569             "com.android.internal.intent.action.REMOTE_BUGREPORT_FINISHED";
570
571     // Used to indicate that an app transition should be animated.
572     static final boolean ANIMATE = true;
573
574     // Determines whether to take full screen screenshots
575     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
576
577     /**
578      * Default value for {@link Settings.Global#NETWORK_ACCESS_TIMEOUT_MS}.
579      */
580     private static final long NETWORK_ACCESS_TIMEOUT_DEFAULT_MS = 200; // 0.2 sec
581
582     /**
583      * State indicating that there is no need for any blocking for network.
584      */
585     @VisibleForTesting
586     static final int NETWORK_STATE_NO_CHANGE = 0;
587
588     /**
589      * State indicating that the main thread needs to be informed about the network wait.
590      */
591     @VisibleForTesting
592     static final int NETWORK_STATE_BLOCK = 1;
593
594     /**
595      * State indicating that any threads waiting for network state to get updated can be unblocked.
596      */
597     @VisibleForTesting
598     static final int NETWORK_STATE_UNBLOCK = 2;
599
600     // Max character limit for a notification title. If the notification title is larger than this
601     // the notification will not be legible to the user.
602     private static final int MAX_BUGREPORT_TITLE_SIZE = 50;
603
604     private static final int NATIVE_DUMP_TIMEOUT_MS = 2000; // 2 seconds;
605
606     /** All system services */
607     SystemServiceManager mSystemServiceManager;
608     AssistUtils mAssistUtils;
609
610     private Installer mInstaller;
611
612     /** Run all ActivityStacks through this */
613     final ActivityStackSupervisor mStackSupervisor;
614     private final KeyguardController mKeyguardController;
615
616     final ActivityStarter mActivityStarter;
617
618     final TaskChangeNotificationController mTaskChangeNotificationController;
619
620     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
621
622     final ArrayList<ActiveInstrumentation> mActiveInstrumentation = new ArrayList<>();
623
624     public final IntentFirewall mIntentFirewall;
625
626     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
627     // default action automatically.  Important for devices without direct input
628     // devices.
629     private boolean mShowDialogs = true;
630
631     private final VrController mVrController;
632
633     // VR Vr2d Display Id.
634     int mVr2dDisplayId = INVALID_DISPLAY;
635
636     // Whether we should use SCHED_FIFO for UI and RenderThreads.
637     private boolean mUseFifoUiScheduling = false;
638
639     BroadcastQueue mFgBroadcastQueue;
640     BroadcastQueue mBgBroadcastQueue;
641     // Convenient for easy iteration over the queues. Foreground is first
642     // so that dispatch of foreground broadcasts gets precedence.
643     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
644
645     BroadcastStats mLastBroadcastStats;
646     BroadcastStats mCurBroadcastStats;
647
648     BroadcastQueue broadcastQueueForIntent(Intent intent) {
649         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
650         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
651                 "Broadcast intent " + intent + " on "
652                 + (isFg ? "foreground" : "background") + " queue");
653         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
654     }
655
656     /**
657      * The last resumed activity. This is identical to the current resumed activity most
658      * of the time but could be different when we're pausing one activity before we resume
659      * another activity.
660      */
661     private ActivityRecord mLastResumedActivity;
662
663     /**
664      * If non-null, we are tracking the time the user spends in the currently focused app.
665      */
666     private AppTimeTracker mCurAppTimeTracker;
667
668     /**
669      * List of intents that were used to start the most recent tasks.
670      */
671     final RecentTasks mRecentTasks;
672
673     /**
674      * For addAppTask: cached of the last activity component that was added.
675      */
676     ComponentName mLastAddedTaskComponent;
677
678     /**
679      * For addAppTask: cached of the last activity uid that was added.
680      */
681     int mLastAddedTaskUid;
682
683     /**
684      * For addAppTask: cached of the last ActivityInfo that was added.
685      */
686     ActivityInfo mLastAddedTaskActivity;
687
688     /**
689      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
690      */
691     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
692
693     /**
694      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
695      */
696     String mDeviceOwnerName;
697
698     final UserController mUserController;
699
700     final AppErrors mAppErrors;
701
702     /**
703      * Dump of the activity state at the time of the last ANR. Cleared after
704      * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
705      */
706     String mLastANRState;
707
708     /**
709      * Indicates the maximum time spent waiting for the network rules to get updated.
710      */
711     @VisibleForTesting
712     long mWaitForNetworkTimeoutMs;
713
714     public boolean canShowErrorDialogs() {
715         return mShowDialogs && !mSleeping && !mShuttingDown
716                 && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
717                 && !(UserManager.isDeviceInDemoMode(mContext)
718                         && mUserController.getCurrentUser().isDemo());
719     }
720
721     private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
722             THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
723
724     static void boostPriorityForLockedSection() {
725         sThreadPriorityBooster.boost();
726     }
727
728     static void resetPriorityAfterLockedSection() {
729         sThreadPriorityBooster.reset();
730     }
731
732     public class PendingAssistExtras extends Binder implements Runnable {
733         public final ActivityRecord activity;
734         public boolean isHome;
735         public final Bundle extras;
736         public final Intent intent;
737         public final String hint;
738         public final IResultReceiver receiver;
739         public final int userHandle;
740         public boolean haveResult = false;
741         public Bundle result = null;
742         public AssistStructure structure = null;
743         public AssistContent content = null;
744         public Bundle receiverExtras;
745
746         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
747                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
748             activity = _activity;
749             extras = _extras;
750             intent = _intent;
751             hint = _hint;
752             receiver = _receiver;
753             receiverExtras = _receiverExtras;
754             userHandle = _userHandle;
755         }
756
757         @Override
758         public void run() {
759             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
760             synchronized (this) {
761                 haveResult = true;
762                 notifyAll();
763             }
764             pendingAssistExtrasTimedOut(this);
765         }
766     }
767
768     final ArrayList<PendingAssistExtras> mPendingAssistExtras
769             = new ArrayList<PendingAssistExtras>();
770
771     /**
772      * Process management.
773      */
774     final ProcessList mProcessList = new ProcessList();
775
776     /**
777      * All of the applications we currently have running organized by name.
778      * The keys are strings of the application package name (as
779      * returned by the package manager), and the keys are ApplicationRecord
780      * objects.
781      */
782     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
783
784     /**
785      * Tracking long-term execution of processes to look for abuse and other
786      * bad app behavior.
787      */
788     final ProcessStatsService mProcessStats;
789
790     /**
791      * The currently running isolated processes.
792      */
793     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
794
795     /**
796      * Counter for assigning isolated process uids, to avoid frequently reusing the
797      * same ones.
798      */
799     int mNextIsolatedProcessUid = 0;
800
801     /**
802      * The currently running heavy-weight process, if any.
803      */
804     ProcessRecord mHeavyWeightProcess = null;
805
806     /**
807      * Non-persistent appId whitelist for background restrictions
808      */
809     int[] mBackgroundAppIdWhitelist = new int[] {
810             BLUETOOTH_UID
811     };
812
813     /**
814      * Broadcast actions that will always be deliverable to unlaunched/background apps
815      */
816     ArraySet<String> mBackgroundLaunchBroadcasts;
817
818     /**
819      * All of the processes we currently have running organized by pid.
820      * The keys are the pid running the application.
821      *
822      * <p>NOTE: This object is protected by its own lock, NOT the global
823      * activity manager lock!
824      */
825     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
826
827     /**
828      * All of the processes that have been forced to be important.  The key
829      * is the pid of the caller who requested it (we hold a death
830      * link on it).
831      */
832     abstract class ImportanceToken implements IBinder.DeathRecipient {
833         final int pid;
834         final IBinder token;
835         final String reason;
836
837         ImportanceToken(int _pid, IBinder _token, String _reason) {
838             pid = _pid;
839             token = _token;
840             reason = _reason;
841         }
842
843         @Override
844         public String toString() {
845             return "ImportanceToken { " + Integer.toHexString(System.identityHashCode(this))
846                     + " " + reason + " " + pid + " " + token + " }";
847         }
848     }
849     final SparseArray<ImportanceToken> mImportantProcesses = new SparseArray<ImportanceToken>();
850
851     /**
852      * List of records for processes that someone had tried to start before the
853      * system was ready.  We don't start them at that point, but ensure they
854      * are started by the time booting is complete.
855      */
856     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
857
858     /**
859      * List of persistent applications that are in the process
860      * of being started.
861      */
862     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
863
864     /**
865      * Processes that are being forcibly torn down.
866      */
867     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
868
869     /**
870      * List of running applications, sorted by recent usage.
871      * The first entry in the list is the least recently used.
872      */
873     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
874
875     /**
876      * Where in mLruProcesses that the processes hosting activities start.
877      */
878     int mLruProcessActivityStart = 0;
879
880     /**
881      * Where in mLruProcesses that the processes hosting services start.
882      * This is after (lower index) than mLruProcessesActivityStart.
883      */
884     int mLruProcessServiceStart = 0;
885
886     /**
887      * List of processes that should gc as soon as things are idle.
888      */
889     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
890
891     /**
892      * Processes we want to collect PSS data from.
893      */
894     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
895
896     private boolean mBinderTransactionTrackingEnabled = false;
897
898     /**
899      * Last time we requested PSS data of all processes.
900      */
901     long mLastFullPssTime = SystemClock.uptimeMillis();
902
903     /**
904      * If set, the next time we collect PSS data we should do a full collection
905      * with data from native processes and the kernel.
906      */
907     boolean mFullPssPending = false;
908
909     /**
910      * This is the process holding what we currently consider to be
911      * the "home" activity.
912      */
913     ProcessRecord mHomeProcess;
914
915     /**
916      * This is the process holding the activity the user last visited that
917      * is in a different process from the one they are currently in.
918      */
919     ProcessRecord mPreviousProcess;
920
921     /**
922      * The time at which the previous process was last visible.
923      */
924     long mPreviousProcessVisibleTime;
925
926     /**
927      * Track all uids that have actively running processes.
928      */
929     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
930
931     /**
932      * This is for verifying the UID report flow.
933      */
934     static final boolean VALIDATE_UID_STATES = true;
935     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
936
937     /**
938      * Packages that the user has asked to have run in screen size
939      * compatibility mode instead of filling the screen.
940      */
941     final CompatModePackages mCompatModePackages;
942
943     /**
944      * Set of IntentSenderRecord objects that are currently active.
945      */
946     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
947             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
948
949     /**
950      * Fingerprints (hashCode()) of stack traces that we've
951      * already logged DropBox entries for.  Guarded by itself.  If
952      * something (rogue user app) forces this over
953      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
954      */
955     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
956     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
957
958     /**
959      * Strict Mode background batched logging state.
960      *
961      * The string buffer is guarded by itself, and its lock is also
962      * used to determine if another batched write is already
963      * in-flight.
964      */
965     private final StringBuilder mStrictModeBuffer = new StringBuilder();
966
967     /**
968      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
969      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
970      */
971     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
972
973     /**
974      * Resolver for broadcast intents to registered receivers.
975      * Holds BroadcastFilter (subclass of IntentFilter).
976      */
977     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
978             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
979         @Override
980         protected boolean allowFilterResult(
981                 BroadcastFilter filter, List<BroadcastFilter> dest) {
982             IBinder target = filter.receiverList.receiver.asBinder();
983             for (int i = dest.size() - 1; i >= 0; i--) {
984                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
985                     return false;
986                 }
987             }
988             return true;
989         }
990
991         @Override
992         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
993             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
994                     || userId == filter.owningUserId) {
995                 return super.newResult(filter, match, userId);
996             }
997             return null;
998         }
999
1000         @Override
1001         protected BroadcastFilter[] newArray(int size) {
1002             return new BroadcastFilter[size];
1003         }
1004
1005         @Override
1006         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
1007             return packageName.equals(filter.packageName);
1008         }
1009     };
1010
1011     /**
1012      * State of all active sticky broadcasts per user.  Keys are the action of the
1013      * sticky Intent, values are an ArrayList of all broadcasted intents with
1014      * that action (which should usually be one).  The SparseArray is keyed
1015      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
1016      * for stickies that are sent to all users.
1017      */
1018     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
1019             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
1020
1021     final ActiveServices mServices;
1022
1023     final static class Association {
1024         final int mSourceUid;
1025         final String mSourceProcess;
1026         final int mTargetUid;
1027         final ComponentName mTargetComponent;
1028         final String mTargetProcess;
1029
1030         int mCount;
1031         long mTime;
1032
1033         int mNesting;
1034         long mStartTime;
1035
1036         // states of the source process when the bind occurred.
1037         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
1038         long mLastStateUptime;
1039         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
1040                 - ActivityManager.MIN_PROCESS_STATE+1];
1041
1042         Association(int sourceUid, String sourceProcess, int targetUid,
1043                 ComponentName targetComponent, String targetProcess) {
1044             mSourceUid = sourceUid;
1045             mSourceProcess = sourceProcess;
1046             mTargetUid = targetUid;
1047             mTargetComponent = targetComponent;
1048             mTargetProcess = targetProcess;
1049         }
1050     }
1051
1052     /**
1053      * When service association tracking is enabled, this is all of the associations we
1054      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
1055      * -> association data.
1056      */
1057     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
1058             mAssociations = new SparseArray<>();
1059     boolean mTrackingAssociations;
1060
1061     /**
1062      * Backup/restore process management
1063      */
1064     String mBackupAppName = null;
1065     BackupRecord mBackupTarget = null;
1066
1067     final ProviderMap mProviderMap;
1068
1069     /**
1070      * List of content providers who have clients waiting for them.  The
1071      * application is currently being launched and the provider will be
1072      * removed from this list once it is published.
1073      */
1074     final ArrayList<ContentProviderRecord> mLaunchingProviders
1075             = new ArrayList<ContentProviderRecord>();
1076
1077     /**
1078      * File storing persisted {@link #mGrantedUriPermissions}.
1079      */
1080     private final AtomicFile mGrantFile;
1081
1082     /** XML constants used in {@link #mGrantFile} */
1083     private static final String TAG_URI_GRANTS = "uri-grants";
1084     private static final String TAG_URI_GRANT = "uri-grant";
1085     private static final String ATTR_USER_HANDLE = "userHandle";
1086     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1087     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1088     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1089     private static final String ATTR_TARGET_PKG = "targetPkg";
1090     private static final String ATTR_URI = "uri";
1091     private static final String ATTR_MODE_FLAGS = "modeFlags";
1092     private static final String ATTR_CREATED_TIME = "createdTime";
1093     private static final String ATTR_PREFIX = "prefix";
1094
1095     /**
1096      * Global set of specific {@link Uri} permissions that have been granted.
1097      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1098      * to {@link UriPermission#uri} to {@link UriPermission}.
1099      */
1100     @GuardedBy("this")
1101     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1102             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1103
1104     public static class GrantUri {
1105         public final int sourceUserId;
1106         public final Uri uri;
1107         public boolean prefix;
1108
1109         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1110             this.sourceUserId = sourceUserId;
1111             this.uri = uri;
1112             this.prefix = prefix;
1113         }
1114
1115         @Override
1116         public int hashCode() {
1117             int hashCode = 1;
1118             hashCode = 31 * hashCode + sourceUserId;
1119             hashCode = 31 * hashCode + uri.hashCode();
1120             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1121             return hashCode;
1122         }
1123
1124         @Override
1125         public boolean equals(Object o) {
1126             if (o instanceof GrantUri) {
1127                 GrantUri other = (GrantUri) o;
1128                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1129                         && prefix == other.prefix;
1130             }
1131             return false;
1132         }
1133
1134         @Override
1135         public String toString() {
1136             String result = uri.toString() + " [user " + sourceUserId + "]";
1137             if (prefix) result += " [prefix]";
1138             return result;
1139         }
1140
1141         public String toSafeString() {
1142             String result = uri.toSafeString() + " [user " + sourceUserId + "]";
1143             if (prefix) result += " [prefix]";
1144             return result;
1145         }
1146
1147         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1148             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1149                     ContentProvider.getUriWithoutUserId(uri), false);
1150         }
1151     }
1152
1153     CoreSettingsObserver mCoreSettingsObserver;
1154
1155     FontScaleSettingObserver mFontScaleSettingObserver;
1156
1157     private final class FontScaleSettingObserver extends ContentObserver {
1158         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1159
1160         public FontScaleSettingObserver() {
1161             super(mHandler);
1162             ContentResolver resolver = mContext.getContentResolver();
1163             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1164         }
1165
1166         @Override
1167         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1168             if (mFontScaleUri.equals(uri)) {
1169                 updateFontScaleIfNeeded(userId);
1170             }
1171         }
1172     }
1173
1174     /**
1175      * Thread-local storage used to carry caller permissions over through
1176      * indirect content-provider access.
1177      */
1178     private class Identity {
1179         public final IBinder token;
1180         public final int pid;
1181         public final int uid;
1182
1183         Identity(IBinder _token, int _pid, int _uid) {
1184             token = _token;
1185             pid = _pid;
1186             uid = _uid;
1187         }
1188     }
1189
1190     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1191
1192     /**
1193      * All information we have collected about the runtime performance of
1194      * any user id that can impact battery performance.
1195      */
1196     final BatteryStatsService mBatteryStatsService;
1197
1198     /**
1199      * Information about component usage
1200      */
1201     UsageStatsManagerInternal mUsageStatsService;
1202
1203     /**
1204      * Access to DeviceIdleController service.
1205      */
1206     DeviceIdleController.LocalService mLocalDeviceIdleController;
1207
1208     /**
1209      * Set of app ids that are whitelisted for device idle and thus background check.
1210      */
1211     int[] mDeviceIdleWhitelist = new int[0];
1212
1213     /**
1214      * Set of app ids that are temporarily allowed to escape bg check due to high-pri message
1215      */
1216     int[] mDeviceIdleTempWhitelist = new int[0];
1217
1218     static final class PendingTempWhitelist {
1219         final int targetUid;
1220         final long duration;
1221         final String tag;
1222
1223         PendingTempWhitelist(int _targetUid, long _duration, String _tag) {
1224             targetUid = _targetUid;
1225             duration = _duration;
1226             tag = _tag;
1227         }
1228     }
1229
1230     final SparseArray<PendingTempWhitelist> mPendingTempWhitelist = new SparseArray<>();
1231
1232     /**
1233      * Information about and control over application operations
1234      */
1235     final AppOpsService mAppOpsService;
1236
1237     /** Current sequencing integer of the configuration, for skipping old configurations. */
1238     private int mConfigurationSeq;
1239
1240     /**
1241      * Temp object used when global and/or display override configuration is updated. It is also
1242      * sent to outer world instead of {@link #getGlobalConfiguration} because we don't trust
1243      * anyone...
1244      */
1245     private Configuration mTempConfig = new Configuration();
1246
1247     private final UpdateConfigurationResult mTmpUpdateConfigurationResult =
1248             new UpdateConfigurationResult();
1249     private static final class UpdateConfigurationResult {
1250         // Configuration changes that were updated.
1251         int changes;
1252         // If the activity was relaunched to match the new configuration.
1253         boolean activityRelaunched;
1254
1255         void reset() {
1256             changes = 0;
1257             activityRelaunched = false;
1258         }
1259     }
1260
1261     boolean mSuppressResizeConfigChanges;
1262
1263     /**
1264      * Hardware-reported OpenGLES version.
1265      */
1266     final int GL_ES_VERSION;
1267
1268     /**
1269      * List of initialization arguments to pass to all processes when binding applications to them.
1270      * For example, references to the commonly used services.
1271      */
1272     HashMap<String, IBinder> mAppBindArgs;
1273     HashMap<String, IBinder> mIsolatedAppBindArgs;
1274
1275     /**
1276      * Temporary to avoid allocations.  Protected by main lock.
1277      */
1278     final StringBuilder mStringBuilder = new StringBuilder(256);
1279
1280     /**
1281      * Used to control how we initialize the service.
1282      */
1283     ComponentName mTopComponent;
1284     String mTopAction = Intent.ACTION_MAIN;
1285     String mTopData;
1286
1287     volatile boolean mProcessesReady = false;
1288     volatile boolean mSystemReady = false;
1289     volatile boolean mOnBattery = false;
1290     volatile int mFactoryTest;
1291
1292     @GuardedBy("this") boolean mBooting = false;
1293     @GuardedBy("this") boolean mCallFinishBooting = false;
1294     @GuardedBy("this") boolean mBootAnimationComplete = false;
1295     @GuardedBy("this") boolean mLaunchWarningShown = false;
1296     @GuardedBy("this") boolean mCheckedForSetup = false;
1297
1298     final Context mContext;
1299
1300     /**
1301      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
1302      * change at runtime. Use mContext for non-UI purposes.
1303      */
1304     final Context mUiContext;
1305
1306     /**
1307      * The time at which we will allow normal application switches again,
1308      * after a call to {@link #stopAppSwitches()}.
1309      */
1310     long mAppSwitchesAllowedTime;
1311
1312     /**
1313      * This is set to true after the first switch after mAppSwitchesAllowedTime
1314      * is set; any switches after that will clear the time.
1315      */
1316     boolean mDidAppSwitch;
1317
1318     /**
1319      * Last time (in uptime) at which we checked for power usage.
1320      */
1321     long mLastPowerCheckUptime;
1322
1323     /**
1324      * Set while we are wanting to sleep, to prevent any
1325      * activities from being started/resumed.
1326      *
1327      * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1328      *
1329      * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1330      * while in the sleep state until there is a pending transition out of sleep, in which case
1331      * mSleeping is set to false, and remains false while awake.
1332      *
1333      * Whether mSleeping can quickly toggled between true/false without the device actually
1334      * display changing states is undefined.
1335      */
1336     private boolean mSleeping = false;
1337
1338     /**
1339      * The process state used for processes that are running the top activities.
1340      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1341      */
1342     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1343
1344     /**
1345      * Set while we are running a voice interaction.  This overrides
1346      * sleeping while it is active.
1347      */
1348     IVoiceInteractionSession mRunningVoice;
1349
1350     /**
1351      * For some direct access we need to power manager.
1352      */
1353     PowerManagerInternal mLocalPowerManager;
1354
1355     /**
1356      * We want to hold a wake lock while running a voice interaction session, since
1357      * this may happen with the screen off and we need to keep the CPU running to
1358      * be able to continue to interact with the user.
1359      */
1360     PowerManager.WakeLock mVoiceWakeLock;
1361
1362     /**
1363      * State of external calls telling us if the device is awake or asleep.
1364      */
1365     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1366
1367     /**
1368      * Set if we are shutting down the system, similar to sleeping.
1369      */
1370     boolean mShuttingDown = false;
1371
1372     /**
1373      * Current sequence id for oom_adj computation traversal.
1374      */
1375     int mAdjSeq = 0;
1376
1377     /**
1378      * Current sequence id for process LRU updating.
1379      */
1380     int mLruSeq = 0;
1381
1382     /**
1383      * Keep track of the non-cached/empty process we last found, to help
1384      * determine how to distribute cached/empty processes next time.
1385      */
1386     int mNumNonCachedProcs = 0;
1387
1388     /**
1389      * Keep track of the number of cached hidden procs, to balance oom adj
1390      * distribution between those and empty procs.
1391      */
1392     int mNumCachedHiddenProcs = 0;
1393
1394     /**
1395      * Keep track of the number of service processes we last found, to
1396      * determine on the next iteration which should be B services.
1397      */
1398     int mNumServiceProcs = 0;
1399     int mNewNumAServiceProcs = 0;
1400     int mNewNumServiceProcs = 0;
1401
1402     /**
1403      * Allow the current computed overall memory level of the system to go down?
1404      * This is set to false when we are killing processes for reasons other than
1405      * memory management, so that the now smaller process list will not be taken as
1406      * an indication that memory is tighter.
1407      */
1408     boolean mAllowLowerMemLevel = false;
1409
1410     /**
1411      * The last computed memory level, for holding when we are in a state that
1412      * processes are going away for other reasons.
1413      */
1414     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1415
1416     /**
1417      * The last total number of process we have, to determine if changes actually look
1418      * like a shrinking number of process due to lower RAM.
1419      */
1420     int mLastNumProcesses;
1421
1422     /**
1423      * The uptime of the last time we performed idle maintenance.
1424      */
1425     long mLastIdleTime = SystemClock.uptimeMillis();
1426
1427     /**
1428      * Total time spent with RAM that has been added in the past since the last idle time.
1429      */
1430     long mLowRamTimeSinceLastIdle = 0;
1431
1432     /**
1433      * If RAM is currently low, when that horrible situation started.
1434      */
1435     long mLowRamStartTime = 0;
1436
1437     /**
1438      * For reporting to battery stats the current top application.
1439      */
1440     private String mCurResumedPackage = null;
1441     private int mCurResumedUid = -1;
1442
1443     /**
1444      * For reporting to battery stats the apps currently running foreground
1445      * service.  The ProcessMap is package/uid tuples; each of these contain
1446      * an array of the currently foreground processes.
1447      */
1448     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1449             = new ProcessMap<ArrayList<ProcessRecord>>();
1450
1451     /**
1452      * Set if the systemServer made a call to enterSafeMode.
1453      */
1454     boolean mSafeMode;
1455
1456     /**
1457      * If true, we are running under a test environment so will sample PSS from processes
1458      * much more rapidly to try to collect better data when the tests are rapidly
1459      * running through apps.
1460      */
1461     boolean mTestPssMode = false;
1462
1463     String mDebugApp = null;
1464     boolean mWaitForDebugger = false;
1465     boolean mDebugTransient = false;
1466     String mOrigDebugApp = null;
1467     boolean mOrigWaitForDebugger = false;
1468     boolean mAlwaysFinishActivities = false;
1469     boolean mForceResizableActivities;
1470     /**
1471      * Flag that indicates if multi-window is enabled.
1472      *
1473      * For any particular form of multi-window to be enabled, generic multi-window must be enabled
1474      * in {@link com.android.internal.R.bool#config_supportsMultiWindow} config or
1475      * {@link Settings.Global#DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES} development option set.
1476      * At least one of the forms of multi-window must be enabled in order for this flag to be
1477      * initialized to 'true'.
1478      *
1479      * @see #mSupportsSplitScreenMultiWindow
1480      * @see #mSupportsFreeformWindowManagement
1481      * @see #mSupportsPictureInPicture
1482      * @see #mSupportsMultiDisplay
1483      */
1484     boolean mSupportsMultiWindow;
1485     boolean mSupportsSplitScreenMultiWindow;
1486     boolean mSupportsFreeformWindowManagement;
1487     boolean mSupportsPictureInPicture;
1488     boolean mSupportsMultiDisplay;
1489     boolean mSupportsLeanbackOnly;
1490     IActivityController mController = null;
1491     boolean mControllerIsAMonkey = false;
1492     String mProfileApp = null;
1493     ProcessRecord mProfileProc = null;
1494     ProfilerInfo mProfilerInfo = null;
1495     int mProfileType = 0;
1496     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1497     String mMemWatchDumpProcName;
1498     String mMemWatchDumpFile;
1499     int mMemWatchDumpPid;
1500     int mMemWatchDumpUid;
1501     String mTrackAllocationApp = null;
1502     String mNativeDebuggingApp = null;
1503
1504     final long[] mTmpLong = new long[2];
1505
1506     private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet();
1507
1508     /**
1509      * A global counter for generating sequence numbers.
1510      * This value will be used when incrementing sequence numbers in individual uidRecords.
1511      *
1512      * Having a global counter ensures that seq numbers are monotonically increasing for a
1513      * particular uid even when the uidRecord is re-created.
1514      */
1515     @GuardedBy("this")
1516     @VisibleForTesting
1517     long mProcStateSeqCounter = 0;
1518
1519     private final Injector mInjector;
1520
1521     static final class ProcessChangeItem {
1522         static final int CHANGE_ACTIVITIES = 1<<0;
1523         int changes;
1524         int uid;
1525         int pid;
1526         int processState;
1527         boolean foregroundActivities;
1528     }
1529
1530     static final class UidObserverRegistration {
1531         final int uid;
1532         final String pkg;
1533         final int which;
1534         final int cutpoint;
1535
1536         final SparseIntArray lastProcStates;
1537
1538         UidObserverRegistration(int _uid, String _pkg, int _which, int _cutpoint) {
1539             uid = _uid;
1540             pkg = _pkg;
1541             which = _which;
1542             cutpoint = _cutpoint;
1543             if (cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
1544                 lastProcStates = new SparseIntArray();
1545             } else {
1546                 lastProcStates = null;
1547             }
1548         }
1549     }
1550
1551     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1552     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1553
1554     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1555     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1556
1557     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1558     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1559
1560     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1561     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1562
1563     OomAdjObserver mCurOomAdjObserver;
1564     int mCurOomAdjUid;
1565
1566     interface OomAdjObserver {
1567         void onOomAdjMessage(String msg);
1568     }
1569
1570     /**
1571      * Runtime CPU use collection thread.  This object's lock is used to
1572      * perform synchronization with the thread (notifying it to run).
1573      */
1574     final Thread mProcessCpuThread;
1575
1576     /**
1577      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1578      * Must acquire this object's lock when accessing it.
1579      * NOTE: this lock will be held while doing long operations (trawling
1580      * through all processes in /proc), so it should never be acquired by
1581      * any critical paths such as when holding the main activity manager lock.
1582      */
1583     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1584             MONITOR_THREAD_CPU_USAGE);
1585     final AtomicLong mLastCpuTime = new AtomicLong(0);
1586     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1587     final CountDownLatch mProcessCpuInitLatch = new CountDownLatch(1);
1588
1589     long mLastWriteTime = 0;
1590
1591     /**
1592      * Used to retain an update lock when the foreground activity is in
1593      * immersive mode.
1594      */
1595     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1596
1597     /**
1598      * Set to true after the system has finished booting.
1599      */
1600     boolean mBooted = false;
1601
1602     WindowManagerService mWindowManager;
1603     final ActivityThread mSystemThread;
1604
1605     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1606         final ProcessRecord mApp;
1607         final int mPid;
1608         final IApplicationThread mAppThread;
1609
1610         AppDeathRecipient(ProcessRecord app, int pid,
1611                 IApplicationThread thread) {
1612             if (DEBUG_ALL) Slog.v(
1613                 TAG, "New death recipient " + this
1614                 + " for thread " + thread.asBinder());
1615             mApp = app;
1616             mPid = pid;
1617             mAppThread = thread;
1618         }
1619
1620         @Override
1621         public void binderDied() {
1622             if (DEBUG_ALL) Slog.v(
1623                 TAG, "Death received in " + this
1624                 + " for thread " + mAppThread.asBinder());
1625             synchronized(ActivityManagerService.this) {
1626                 appDiedLocked(mApp, mPid, mAppThread, true);
1627             }
1628         }
1629     }
1630
1631     static final int SHOW_ERROR_UI_MSG = 1;
1632     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1633     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1634     static final int UPDATE_CONFIGURATION_MSG = 4;
1635     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1636     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1637     static final int SERVICE_TIMEOUT_MSG = 12;
1638     static final int UPDATE_TIME_ZONE = 13;
1639     static final int SHOW_UID_ERROR_UI_MSG = 14;
1640     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1641     static final int PROC_START_TIMEOUT_MSG = 20;
1642     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1643     static final int KILL_APPLICATION_MSG = 22;
1644     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1645     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1646     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1647     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1648     static final int CHECK_EXCESSIVE_POWER_USE_MSG = 27;
1649     static final int CLEAR_DNS_CACHE_MSG = 28;
1650     static final int UPDATE_HTTP_PROXY_MSG = 29;
1651     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1652     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1653     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1654     static final int REPORT_MEM_USAGE_MSG = 33;
1655     static final int REPORT_USER_SWITCH_MSG = 34;
1656     static final int CONTINUE_USER_SWITCH_MSG = 35;
1657     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1658     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1659     static final int PERSIST_URI_GRANTS_MSG = 38;
1660     static final int REQUEST_ALL_PSS_MSG = 39;
1661     static final int START_PROFILES_MSG = 40;
1662     static final int UPDATE_TIME_PREFERENCE_MSG = 41;
1663     static final int SYSTEM_USER_START_MSG = 42;
1664     static final int SYSTEM_USER_CURRENT_MSG = 43;
1665     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1666     static final int FINISH_BOOTING_MSG = 45;
1667     static final int START_USER_SWITCH_UI_MSG = 46;
1668     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1669     static final int DISMISS_DIALOG_UI_MSG = 48;
1670     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
1671     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
1672     static final int DELETE_DUMPHEAP_MSG = 51;
1673     static final int FOREGROUND_PROFILE_CHANGED_MSG = 52;
1674     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
1675     static final int REPORT_TIME_TRACKER_MSG = 54;
1676     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 55;
1677     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
1678     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
1679     static final int IDLE_UIDS_MSG = 58;
1680     static final int SYSTEM_USER_UNLOCK_MSG = 59;
1681     static final int LOG_STACK_STATE = 60;
1682     static final int VR_MODE_CHANGE_MSG = 61;
1683     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 62;
1684     static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
1685     static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
1686     static final int NOTIFY_VR_SLEEPING_MSG = 65;
1687     static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
1688     static final int DISPATCH_PENDING_INTENT_CANCEL_MSG = 67;
1689     static final int PUSH_TEMP_WHITELIST_UI_MSG = 68;
1690     static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
1691     static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
1692     static final int START_USER_SWITCH_FG_MSG = 712;
1693     static final int NOTIFY_VR_KEYGUARD_MSG = 74;
1694
1695     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1696     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1697     static final int FIRST_COMPAT_MODE_MSG = 300;
1698     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1699
1700     static ServiceThread sKillThread = null;
1701     static KillHandler sKillHandler = null;
1702
1703     CompatModeDialog mCompatModeDialog;
1704     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1705     long mLastMemUsageReportTime = 0;
1706
1707     /**
1708      * Flag whether the current user is a "monkey", i.e. whether
1709      * the UI is driven by a UI automation tool.
1710      */
1711     private boolean mUserIsMonkey;
1712
1713     /** Flag whether the device has a Recents UI */
1714     boolean mHasRecents;
1715
1716     /** The dimensions of the thumbnails in the Recents UI. */
1717     int mThumbnailWidth;
1718     int mThumbnailHeight;
1719     float mFullscreenThumbnailScale;
1720
1721     final ServiceThread mHandlerThread;
1722     final MainHandler mHandler;
1723     final Handler mUiHandler;
1724
1725     final ActivityManagerConstants mConstants;
1726
1727     PackageManagerInternal mPackageManagerInt;
1728
1729     // VoiceInteraction session ID that changes for each new request except when
1730     // being called for multiwindow assist in a single session.
1731     private int mViSessionId = 1000;
1732
1733     final boolean mPermissionReviewRequired;
1734
1735     private static String sTheRealBuildSerial = Build.UNKNOWN;
1736
1737     /**
1738      * Current global configuration information. Contains general settings for the entire system,
1739      * also corresponds to the merged configuration of the default display.
1740      */
1741     Configuration getGlobalConfiguration() {
1742         return mStackSupervisor.getConfiguration();
1743     }
1744
1745     final class KillHandler extends Handler {
1746         static final int KILL_PROCESS_GROUP_MSG = 4000;
1747
1748         public KillHandler(Looper looper) {
1749             super(looper, null, true);
1750         }
1751
1752         @Override
1753         public void handleMessage(Message msg) {
1754             switch (msg.what) {
1755                 case KILL_PROCESS_GROUP_MSG:
1756                 {
1757                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1758                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1759                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1760                 }
1761                 break;
1762
1763                 default:
1764                     super.handleMessage(msg);
1765             }
1766         }
1767     }
1768
1769     final class UiHandler extends Handler {
1770         public UiHandler() {
1771             super(com.android.server.UiThread.get().getLooper(), null, true);
1772         }
1773
1774         @Override
1775         public void handleMessage(Message msg) {
1776             switch (msg.what) {
1777             case SHOW_ERROR_UI_MSG: {
1778                 mAppErrors.handleShowAppErrorUi(msg);
1779                 ensureBootCompleted();
1780             } break;
1781             case SHOW_NOT_RESPONDING_UI_MSG: {
1782                 mAppErrors.handleShowAnrUi(msg);
1783                 ensureBootCompleted();
1784             } break;
1785             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1786                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1787                 synchronized (ActivityManagerService.this) {
1788                     ProcessRecord proc = (ProcessRecord) data.get("app");
1789                     if (proc == null) {
1790                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1791                         break;
1792                     }
1793                     if (proc.crashDialog != null) {
1794                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1795                         return;
1796                     }
1797                     AppErrorResult res = (AppErrorResult) data.get("result");
1798                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1799                         Dialog d = new StrictModeViolationDialog(mUiContext,
1800                                 ActivityManagerService.this, res, proc);
1801                         d.show();
1802                         proc.crashDialog = d;
1803                     } else {
1804                         // The device is asleep, so just pretend that the user
1805                         // saw a crash dialog and hit "force quit".
1806                         res.set(0);
1807                     }
1808                 }
1809                 ensureBootCompleted();
1810             } break;
1811             case SHOW_FACTORY_ERROR_UI_MSG: {
1812                 Dialog d = new FactoryErrorDialog(
1813                         mUiContext, msg.getData().getCharSequence("msg"));
1814                 d.show();
1815                 ensureBootCompleted();
1816             } break;
1817             case WAIT_FOR_DEBUGGER_UI_MSG: {
1818                 synchronized (ActivityManagerService.this) {
1819                     ProcessRecord app = (ProcessRecord)msg.obj;
1820                     if (msg.arg1 != 0) {
1821                         if (!app.waitedForDebugger) {
1822                             Dialog d = new AppWaitingForDebuggerDialog(
1823                                     ActivityManagerService.this,
1824                                     mUiContext, app);
1825                             app.waitDialog = d;
1826                             app.waitedForDebugger = true;
1827                             d.show();
1828                         }
1829                     } else {
1830                         if (app.waitDialog != null) {
1831                             app.waitDialog.dismiss();
1832                             app.waitDialog = null;
1833                         }
1834                     }
1835                 }
1836             } break;
1837             case SHOW_UID_ERROR_UI_MSG: {
1838                 if (mShowDialogs) {
1839                     AlertDialog d = new BaseErrorDialog(mUiContext);
1840                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1841                     d.setCancelable(false);
1842                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1843                     d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
1844                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1845                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1846                     d.show();
1847                 }
1848             } break;
1849             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1850                 if (mShowDialogs) {
1851                     AlertDialog d = new BaseErrorDialog(mUiContext);
1852                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1853                     d.setCancelable(false);
1854                     d.setTitle(mUiContext.getText(R.string.android_system_label));
1855                     d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
1856                     d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
1857                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1858                     d.show();
1859                 }
1860             } break;
1861             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1862                 synchronized (ActivityManagerService.this) {
1863                     ActivityRecord ar = (ActivityRecord) msg.obj;
1864                     if (mCompatModeDialog != null) {
1865                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1866                                 ar.info.applicationInfo.packageName)) {
1867                             return;
1868                         }
1869                         mCompatModeDialog.dismiss();
1870                         mCompatModeDialog = null;
1871                     }
1872                     if (ar != null && false) {
1873                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1874                                 ar.packageName)) {
1875                             int mode = mCompatModePackages.computeCompatModeLocked(
1876                                     ar.info.applicationInfo);
1877                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1878                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1879                                 mCompatModeDialog = new CompatModeDialog(
1880                                         ActivityManagerService.this, mUiContext,
1881                                         ar.info.applicationInfo);
1882                                 mCompatModeDialog.show();
1883                             }
1884                         }
1885                     }
1886                 }
1887                 break;
1888             }
1889             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1890                 synchronized (ActivityManagerService.this) {
1891                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1892                     if (mUnsupportedDisplaySizeDialog != null) {
1893                         mUnsupportedDisplaySizeDialog.dismiss();
1894                         mUnsupportedDisplaySizeDialog = null;
1895                     }
1896                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1897                             ar.packageName)) {
1898                         // TODO(multi-display): Show dialog on appropriate display.
1899                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1900                                 ActivityManagerService.this, mUiContext, ar.info.applicationInfo);
1901                         mUnsupportedDisplaySizeDialog.show();
1902                     }
1903                 }
1904                 break;
1905             }
1906             case START_USER_SWITCH_UI_MSG: {
1907                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1908                 break;
1909             }
1910             case DISMISS_DIALOG_UI_MSG: {
1911                 final Dialog d = (Dialog) msg.obj;
1912                 d.dismiss();
1913                 break;
1914             }
1915             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1916                 dispatchProcessesChanged();
1917                 break;
1918             }
1919             case DISPATCH_PROCESS_DIED_UI_MSG: {
1920                 final int pid = msg.arg1;
1921                 final int uid = msg.arg2;
1922                 dispatchProcessDied(pid, uid);
1923                 break;
1924             }
1925             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1926                 dispatchUidsChanged();
1927             } break;
1928             case DISPATCH_OOM_ADJ_OBSERVER_MSG: {
1929                 dispatchOomAdjObserver((String)msg.obj);
1930             } break;
1931             case PUSH_TEMP_WHITELIST_UI_MSG: {
1932                 pushTempWhitelist();
1933             } break;
1934             }
1935         }
1936     }
1937
1938     final class MainHandler extends Handler {
1939         public MainHandler(Looper looper) {
1940             super(looper, null, true);
1941         }
1942
1943         @Override
1944         public void handleMessage(Message msg) {
1945             switch (msg.what) {
1946             case UPDATE_CONFIGURATION_MSG: {
1947                 final ContentResolver resolver = mContext.getContentResolver();
1948                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1949                         msg.arg1);
1950             } break;
1951             case GC_BACKGROUND_PROCESSES_MSG: {
1952                 synchronized (ActivityManagerService.this) {
1953                     performAppGcsIfAppropriateLocked();
1954                 }
1955             } break;
1956             case SERVICE_TIMEOUT_MSG: {
1957                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1958             } break;
1959             case SERVICE_FOREGROUND_TIMEOUT_MSG: {
1960                 mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
1961             } break;
1962             case SERVICE_FOREGROUND_CRASH_MSG: {
1963                 mServices.serviceForegroundCrash((ProcessRecord)msg.obj);
1964             } break;
1965             case DISPATCH_PENDING_INTENT_CANCEL_MSG: {
1966                 RemoteCallbackList<IResultReceiver> callbacks
1967                         = (RemoteCallbackList<IResultReceiver>)msg.obj;
1968                 int N = callbacks.beginBroadcast();
1969                 for (int i = 0; i < N; i++) {
1970                     try {
1971                         callbacks.getBroadcastItem(i).send(Activity.RESULT_CANCELED, null);
1972                     } catch (RemoteException e) {
1973                     }
1974                 }
1975                 callbacks.finishBroadcast();
1976             } break;
1977             case UPDATE_TIME_ZONE: {
1978                 synchronized (ActivityManagerService.this) {
1979                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1980                         ProcessRecord r = mLruProcesses.get(i);
1981                         if (r.thread != null) {
1982                             try {
1983                                 r.thread.updateTimeZone();
1984                             } catch (RemoteException ex) {
1985                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1986                             }
1987                         }
1988                     }
1989                 }
1990             } break;
1991             case CLEAR_DNS_CACHE_MSG: {
1992                 synchronized (ActivityManagerService.this) {
1993                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1994                         ProcessRecord r = mLruProcesses.get(i);
1995                         if (r.thread != null) {
1996                             try {
1997                                 r.thread.clearDnsCache();
1998                             } catch (RemoteException ex) {
1999                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
2000                             }
2001                         }
2002                     }
2003                 }
2004             } break;
2005             case UPDATE_HTTP_PROXY_MSG: {
2006                 ProxyInfo proxy = (ProxyInfo)msg.obj;
2007                 String host = "";
2008                 String port = "";
2009                 String exclList = "";
2010                 Uri pacFileUrl = Uri.EMPTY;
2011                 if (proxy != null) {
2012                     host = proxy.getHost();
2013                     port = Integer.toString(proxy.getPort());
2014                     exclList = proxy.getExclusionListAsString();
2015                     pacFileUrl = proxy.getPacFileUrl();
2016                 }
2017                 synchronized (ActivityManagerService.this) {
2018                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2019                         ProcessRecord r = mLruProcesses.get(i);
2020                         if (r.thread != null) {
2021                             try {
2022                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
2023                             } catch (RemoteException ex) {
2024                                 Slog.w(TAG, "Failed to update http proxy for: " +
2025                                         r.info.processName);
2026                             }
2027                         }
2028                     }
2029                 }
2030             } break;
2031             case PROC_START_TIMEOUT_MSG: {
2032                 ProcessRecord app = (ProcessRecord)msg.obj;
2033                 synchronized (ActivityManagerService.this) {
2034                     processStartTimedOutLocked(app);
2035                 }
2036             } break;
2037             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
2038                 ProcessRecord app = (ProcessRecord)msg.obj;
2039                 synchronized (ActivityManagerService.this) {
2040                     processContentProviderPublishTimedOutLocked(app);
2041                 }
2042             } break;
2043             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
2044                 synchronized (ActivityManagerService.this) {
2045                     mActivityStarter.doPendingActivityLaunchesLocked(true);
2046                 }
2047             } break;
2048             case KILL_APPLICATION_MSG: {
2049                 synchronized (ActivityManagerService.this) {
2050                     final int appId = msg.arg1;
2051                     final int userId = msg.arg2;
2052                     Bundle bundle = (Bundle)msg.obj;
2053                     String pkg = bundle.getString("pkg");
2054                     String reason = bundle.getString("reason");
2055                     forceStopPackageLocked(pkg, appId, false, false, true, false,
2056                             false, userId, reason);
2057                 }
2058             } break;
2059             case FINALIZE_PENDING_INTENT_MSG: {
2060                 ((PendingIntentRecord)msg.obj).completeFinalize();
2061             } break;
2062             case POST_HEAVY_NOTIFICATION_MSG: {
2063                 INotificationManager inm = NotificationManager.getService();
2064                 if (inm == null) {
2065                     return;
2066                 }
2067
2068                 ActivityRecord root = (ActivityRecord)msg.obj;
2069                 ProcessRecord process = root.app;
2070                 if (process == null) {
2071                     return;
2072                 }
2073
2074                 try {
2075                     Context context = mContext.createPackageContext(process.info.packageName, 0);
2076                     String text = mContext.getString(R.string.heavy_weight_notification,
2077                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
2078                     Notification notification =
2079                             new Notification.Builder(context, SystemNotificationChannels.DEVELOPER)
2080                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2081                             .setWhen(0)
2082                             .setOngoing(true)
2083                             .setTicker(text)
2084                             .setColor(mContext.getColor(
2085                                     com.android.internal.R.color.system_notification_accent_color))
2086                             .setContentTitle(text)
2087                             .setContentText(
2088                                     mContext.getText(R.string.heavy_weight_notification_detail))
2089                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2090                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2091                                     new UserHandle(root.userId)))
2092                             .build();
2093                     try {
2094                         inm.enqueueNotificationWithTag("android", "android", null,
2095                                 SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,
2096                                 notification, root.userId);
2097                     } catch (RuntimeException e) {
2098                         Slog.w(ActivityManagerService.TAG,
2099                                 "Error showing notification for heavy-weight app", e);
2100                     } catch (RemoteException e) {
2101                     }
2102                 } catch (NameNotFoundException e) {
2103                     Slog.w(TAG, "Unable to create context for heavy notification", e);
2104                 }
2105             } break;
2106             case CANCEL_HEAVY_NOTIFICATION_MSG: {
2107                 INotificationManager inm = NotificationManager.getService();
2108                 if (inm == null) {
2109                     return;
2110                 }
2111                 try {
2112                     inm.cancelNotificationWithTag("android", null,
2113                             SystemMessage.NOTE_HEAVY_WEIGHT_NOTIFICATION,  msg.arg1);
2114                 } catch (RuntimeException e) {
2115                     Slog.w(ActivityManagerService.TAG,
2116                             "Error canceling notification for service", e);
2117                 } catch (RemoteException e) {
2118                 }
2119             } break;
2120             case CHECK_EXCESSIVE_POWER_USE_MSG: {
2121                 synchronized (ActivityManagerService.this) {
2122                     checkExcessivePowerUsageLocked();
2123                     removeMessages(CHECK_EXCESSIVE_POWER_USE_MSG);
2124                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
2125                     sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
2126                 }
2127             } break;
2128             case REPORT_MEM_USAGE_MSG: {
2129                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
2130                 Thread thread = new Thread() {
2131                     @Override public void run() {
2132                         reportMemUsage(memInfos);
2133                     }
2134                 };
2135                 thread.start();
2136                 break;
2137             }
2138             case START_USER_SWITCH_FG_MSG: {
2139                 mUserController.startUserInForeground(msg.arg1);
2140                 break;
2141             }
2142             case REPORT_USER_SWITCH_MSG: {
2143                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2144                 break;
2145             }
2146             case CONTINUE_USER_SWITCH_MSG: {
2147                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2148                 break;
2149             }
2150             case USER_SWITCH_TIMEOUT_MSG: {
2151                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
2152                 break;
2153             }
2154             case IMMERSIVE_MODE_LOCK_MSG: {
2155                 final boolean nextState = (msg.arg1 != 0);
2156                 if (mUpdateLock.isHeld() != nextState) {
2157                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
2158                             "Applying new update lock state '" + nextState
2159                             + "' for " + (ActivityRecord)msg.obj);
2160                     if (nextState) {
2161                         mUpdateLock.acquire();
2162                     } else {
2163                         mUpdateLock.release();
2164                     }
2165                 }
2166                 break;
2167             }
2168             case PERSIST_URI_GRANTS_MSG: {
2169                 writeGrantedUriPermissions();
2170                 break;
2171             }
2172             case REQUEST_ALL_PSS_MSG: {
2173                 synchronized (ActivityManagerService.this) {
2174                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2175                 }
2176                 break;
2177             }
2178             case START_PROFILES_MSG: {
2179                 synchronized (ActivityManagerService.this) {
2180                     mUserController.startProfilesLocked();
2181                 }
2182                 break;
2183             }
2184             case UPDATE_TIME_PREFERENCE_MSG: {
2185                 // The user's time format preference might have changed.
2186                 // For convenience we re-use the Intent extra values.
2187                 synchronized (ActivityManagerService.this) {
2188                     for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2189                         ProcessRecord r = mLruProcesses.get(i);
2190                         if (r.thread != null) {
2191                             try {
2192                                 r.thread.updateTimePrefs(msg.arg1);
2193                             } catch (RemoteException ex) {
2194                                 Slog.w(TAG, "Failed to update preferences for: "
2195                                         + r.info.processName);
2196                             }
2197                         }
2198                     }
2199                 }
2200                 break;
2201             }
2202             case SYSTEM_USER_START_MSG: {
2203                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2204                         Integer.toString(msg.arg1), msg.arg1);
2205                 mSystemServiceManager.startUser(msg.arg1);
2206                 break;
2207             }
2208             case SYSTEM_USER_UNLOCK_MSG: {
2209                 final int userId = msg.arg1;
2210                 mSystemServiceManager.unlockUser(userId);
2211                 synchronized (ActivityManagerService.this) {
2212                     mRecentTasks.loadUserRecentsLocked(userId);
2213                 }
2214                 if (userId == UserHandle.USER_SYSTEM) {
2215                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2216                 }
2217                 installEncryptionUnawareProviders(userId);
2218                 mUserController.finishUserUnlocked((UserState) msg.obj);
2219                 break;
2220             }
2221             case SYSTEM_USER_CURRENT_MSG: {
2222                 mBatteryStatsService.noteEvent(
2223                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2224                         Integer.toString(msg.arg2), msg.arg2);
2225                 mBatteryStatsService.noteEvent(
2226                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2227                         Integer.toString(msg.arg1), msg.arg1);
2228                 mSystemServiceManager.switchUser(msg.arg1);
2229                 break;
2230             }
2231             case ENTER_ANIMATION_COMPLETE_MSG: {
2232                 synchronized (ActivityManagerService.this) {
2233                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2234                     if (r != null && r.app != null && r.app.thread != null) {
2235                         try {
2236                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2237                         } catch (RemoteException e) {
2238                         }
2239                     }
2240                 }
2241                 break;
2242             }
2243             case FINISH_BOOTING_MSG: {
2244                 if (msg.arg1 != 0) {
2245                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2246                     finishBooting();
2247                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2248                 }
2249                 if (msg.arg2 != 0) {
2250                     enableScreenAfterBoot();
2251                 }
2252                 break;
2253             }
2254             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2255                 try {
2256                     Locale l = (Locale) msg.obj;
2257                     IBinder service = ServiceManager.getService("mount");
2258                     IStorageManager storageManager = IStorageManager.Stub.asInterface(service);
2259                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2260                     storageManager.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2261                 } catch (RemoteException e) {
2262                     Log.e(TAG, "Error storing locale for decryption UI", e);
2263                 }
2264                 break;
2265             }
2266             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2267                 final int uid = msg.arg1;
2268                 final byte[] firstPacket = (byte[]) msg.obj;
2269
2270                 synchronized (mPidsSelfLocked) {
2271                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2272                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2273                         if (p.uid == uid) {
2274                             try {
2275                                 p.thread.notifyCleartextNetwork(firstPacket);
2276                             } catch (RemoteException ignored) {
2277                             }
2278                         }
2279                     }
2280                 }
2281                 break;
2282             }
2283             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2284                 final String procName;
2285                 final int uid;
2286                 final long memLimit;
2287                 final String reportPackage;
2288                 synchronized (ActivityManagerService.this) {
2289                     procName = mMemWatchDumpProcName;
2290                     uid = mMemWatchDumpUid;
2291                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2292                     if (val == null) {
2293                         val = mMemWatchProcesses.get(procName, 0);
2294                     }
2295                     if (val != null) {
2296                         memLimit = val.first;
2297                         reportPackage = val.second;
2298                     } else {
2299                         memLimit = 0;
2300                         reportPackage = null;
2301                     }
2302                 }
2303                 if (procName == null) {
2304                     return;
2305                 }
2306
2307                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2308                         "Showing dump heap notification from " + procName + "/" + uid);
2309
2310                 INotificationManager inm = NotificationManager.getService();
2311                 if (inm == null) {
2312                     return;
2313                 }
2314
2315                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2316
2317
2318                 Intent deleteIntent = new Intent();
2319                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2320                 Intent intent = new Intent();
2321                 intent.setClassName("android", DumpHeapActivity.class.getName());
2322                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2323                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2324                 if (reportPackage != null) {
2325                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2326                 }
2327                 int userId = UserHandle.getUserId(uid);
2328                 Notification notification =
2329                         new Notification.Builder(mContext, SystemNotificationChannels.DEVELOPER)
2330                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2331                         .setWhen(0)
2332                         .setOngoing(true)
2333                         .setAutoCancel(true)
2334                         .setTicker(text)
2335                         .setColor(mContext.getColor(
2336                                 com.android.internal.R.color.system_notification_accent_color))
2337                         .setContentTitle(text)
2338                         .setContentText(
2339                                 mContext.getText(R.string.dump_heap_notification_detail))
2340                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2341                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2342                                 new UserHandle(userId)))
2343                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2344                                 deleteIntent, 0, UserHandle.SYSTEM))
2345                         .build();
2346
2347                 try {
2348                     inm.enqueueNotificationWithTag("android", "android", null,
2349                             SystemMessage.NOTE_DUMP_HEAP_NOTIFICATION,
2350                             notification, userId);
2351                 } catch (RuntimeException e) {
2352                     Slog.w(ActivityManagerService.TAG,
2353                             "Error showing notification for dump heap", e);
2354                 } catch (RemoteException e) {
2355                 }
2356             } break;
2357             case DELETE_DUMPHEAP_MSG: {
2358                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2359                         null, DumpHeapActivity.JAVA_URI,
2360                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2361                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2362                         UserHandle.myUserId());
2363                 synchronized (ActivityManagerService.this) {
2364                     mMemWatchDumpFile = null;
2365                     mMemWatchDumpProcName = null;
2366                     mMemWatchDumpPid = -1;
2367                     mMemWatchDumpUid = -1;
2368                 }
2369             } break;
2370             case FOREGROUND_PROFILE_CHANGED_MSG: {
2371                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2372             } break;
2373             case REPORT_TIME_TRACKER_MSG: {
2374                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2375                 tracker.deliverResult(mContext);
2376             } break;
2377             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2378                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2379             } break;
2380             case REPORT_LOCKED_BOOT_COMPLETE_MSG: {
2381                 mUserController.dispatchLockedBootComplete(msg.arg1);
2382             } break;
2383             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2384                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2385                 try {
2386                     connection.shutdown();
2387                 } catch (RemoteException e) {
2388                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2389                 }
2390                 // Only a UiAutomation can set this flag and now that
2391                 // it is finished we make sure it is reset to its default.
2392                 mUserIsMonkey = false;
2393             } break;
2394             case IDLE_UIDS_MSG: {
2395                 idleUids();
2396             } break;
2397             case VR_MODE_CHANGE_MSG: {
2398                 if (!mVrController.onVrModeChanged((ActivityRecord) msg.obj)) {
2399                     return;
2400                 }
2401                 synchronized (ActivityManagerService.this) {
2402                     final boolean disableNonVrUi = mVrController.shouldDisableNonVrUiLocked();
2403                     mWindowManager.disableNonVrUi(disableNonVrUi);
2404                     if (disableNonVrUi) {
2405                         // If we are in a VR mode where Picture-in-Picture mode is unsupported,
2406                         // then remove the pinned stack.
2407                         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
2408                                 PINNED_STACK_ID);
2409                         if (pinnedStack != null) {
2410                             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
2411                         }
2412                     }
2413                 }
2414             } break;
2415             case NOTIFY_VR_SLEEPING_MSG: {
2416                 notifyVrManagerOfSleepState(msg.arg1 != 0);
2417             } break;
2418             case NOTIFY_VR_KEYGUARD_MSG: {
2419                 notifyVrManagerOfKeyguardState(msg.arg1 != 0);
2420             } break;
2421             case HANDLE_TRUST_STORAGE_UPDATE_MSG: {
2422                 synchronized (ActivityManagerService.this) {
2423                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2424                         ProcessRecord r = mLruProcesses.get(i);
2425                         if (r.thread != null) {
2426                             try {
2427                                 r.thread.handleTrustStorageUpdate();
2428                             } catch (RemoteException ex) {
2429                                 Slog.w(TAG, "Failed to handle trust storage update for: " +
2430                                         r.info.processName);
2431                             }
2432                         }
2433                     }
2434                 }
2435             } break;
2436             }
2437         }
2438     };
2439
2440     static final int COLLECT_PSS_BG_MSG = 1;
2441
2442     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2443         @Override
2444         public void handleMessage(Message msg) {
2445             switch (msg.what) {
2446             case COLLECT_PSS_BG_MSG: {
2447                 long start = SystemClock.uptimeMillis();
2448                 MemInfoReader memInfo = null;
2449                 synchronized (ActivityManagerService.this) {
2450                     if (mFullPssPending) {
2451                         mFullPssPending = false;
2452                         memInfo = new MemInfoReader();
2453                     }
2454                 }
2455                 if (memInfo != null) {
2456                     updateCpuStatsNow();
2457                     long nativeTotalPss = 0;
2458                     final List<ProcessCpuTracker.Stats> stats;
2459                     synchronized (mProcessCpuTracker) {
2460                         stats = mProcessCpuTracker.getStats( (st)-> {
2461                             return st.vsize > 0 && st.uid < FIRST_APPLICATION_UID;
2462                         });
2463                     }
2464                     final int N = stats.size();
2465                     for (int j = 0; j < N; j++) {
2466                         synchronized (mPidsSelfLocked) {
2467                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2468                                 // This is one of our own processes; skip it.
2469                                 continue;
2470                             }
2471                         }
2472                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2473                     }
2474                     memInfo.readMemInfo();
2475                     synchronized (ActivityManagerService.this) {
2476                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2477                                 + (SystemClock.uptimeMillis()-start) + "ms");
2478                         final long cachedKb = memInfo.getCachedSizeKb();
2479                         final long freeKb = memInfo.getFreeSizeKb();
2480                         final long zramKb = memInfo.getZramTotalSizeKb();
2481                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2482                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2483                                 kernelKb*1024, nativeTotalPss*1024);
2484                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2485                                 nativeTotalPss);
2486                     }
2487                 }
2488
2489                 int num = 0;
2490                 long[] tmp = new long[2];
2491                 do {
2492                     ProcessRecord proc;
2493                     int procState;
2494                     int pid;
2495                     long lastPssTime;
2496                     synchronized (ActivityManagerService.this) {
2497                         if (mPendingPssProcesses.size() <= 0) {
2498                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2499                                     "Collected PSS of " + num + " processes in "
2500                                     + (SystemClock.uptimeMillis() - start) + "ms");
2501                             mPendingPssProcesses.clear();
2502                             return;
2503                         }
2504                         proc = mPendingPssProcesses.remove(0);
2505                         procState = proc.pssProcState;
2506                         lastPssTime = proc.lastPssTime;
2507                         if (proc.thread != null && procState == proc.setProcState
2508                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2509                                         < SystemClock.uptimeMillis()) {
2510                             pid = proc.pid;
2511                         } else {
2512                             proc = null;
2513                             pid = 0;
2514                         }
2515                     }
2516                     if (proc != null) {
2517                         long pss = Debug.getPss(pid, tmp, null);
2518                         synchronized (ActivityManagerService.this) {
2519                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2520                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2521                                 num++;
2522                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2523                                         SystemClock.uptimeMillis());
2524                             }
2525                         }
2526                     }
2527                 } while (true);
2528             }
2529             }
2530         }
2531     };
2532
2533     public void setSystemProcess() {
2534         try {
2535             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2536             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2537             ServiceManager.addService("meminfo", new MemBinder(this));
2538             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2539             ServiceManager.addService("dbinfo", new DbBinder(this));
2540             if (MONITOR_CPU_USAGE) {
2541                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2542             }
2543             ServiceManager.addService("permission", new PermissionController(this));
2544             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2545
2546             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2547                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2548             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2549
2550             synchronized (this) {
2551                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2552                 app.persistent = true;
2553                 app.pid = MY_PID;
2554                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2555                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2556                 synchronized (mPidsSelfLocked) {
2557                     mPidsSelfLocked.put(app.pid, app);
2558                 }
2559                 updateLruProcessLocked(app, false, null);
2560                 updateOomAdjLocked();
2561             }
2562         } catch (PackageManager.NameNotFoundException e) {
2563             throw new RuntimeException(
2564                     "Unable to find android system package", e);
2565         }
2566     }
2567
2568     public void setWindowManager(WindowManagerService wm) {
2569         mWindowManager = wm;
2570         mStackSupervisor.setWindowManager(wm);
2571         mActivityStarter.setWindowManager(wm);
2572     }
2573
2574     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2575         mUsageStatsService = usageStatsManager;
2576     }
2577
2578     public void startObservingNativeCrashes() {
2579         final NativeCrashListener ncl = new NativeCrashListener(this);
2580         ncl.start();
2581     }
2582
2583     public IAppOpsService getAppOpsService() {
2584         return mAppOpsService;
2585     }
2586
2587     static class MemBinder extends Binder {
2588         ActivityManagerService mActivityManagerService;
2589         MemBinder(ActivityManagerService activityManagerService) {
2590             mActivityManagerService = activityManagerService;
2591         }
2592
2593         @Override
2594         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2595             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2596                     "meminfo", pw)) return;
2597             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2598         }
2599     }
2600
2601     static class GraphicsBinder extends Binder {
2602         ActivityManagerService mActivityManagerService;
2603         GraphicsBinder(ActivityManagerService activityManagerService) {
2604             mActivityManagerService = activityManagerService;
2605         }
2606
2607         @Override
2608         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2609             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2610                     "gfxinfo", pw)) return;
2611             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2612         }
2613     }
2614
2615     static class DbBinder extends Binder {
2616         ActivityManagerService mActivityManagerService;
2617         DbBinder(ActivityManagerService activityManagerService) {
2618             mActivityManagerService = activityManagerService;
2619         }
2620
2621         @Override
2622         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2623             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2624                     "dbinfo", pw)) return;
2625             mActivityManagerService.dumpDbInfo(fd, pw, args);
2626         }
2627     }
2628
2629     static class CpuBinder extends Binder {
2630         ActivityManagerService mActivityManagerService;
2631         CpuBinder(ActivityManagerService activityManagerService) {
2632             mActivityManagerService = activityManagerService;
2633         }
2634
2635         @Override
2636         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2637             if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
2638                     "cpuinfo", pw)) return;
2639             synchronized (mActivityManagerService.mProcessCpuTracker) {
2640                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2641                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2642                         SystemClock.uptimeMillis()));
2643             }
2644         }
2645     }
2646
2647     public static final class Lifecycle extends SystemService {
2648         private final ActivityManagerService mService;
2649
2650         public Lifecycle(Context context) {
2651             super(context);
2652             mService = new ActivityManagerService(context);
2653         }
2654
2655         @Override
2656         public void onStart() {
2657             mService.start();
2658         }
2659
2660         @Override
2661         public void onCleanupUser(int userId) {
2662             mService.mBatteryStatsService.onCleanupUser(userId);
2663         }
2664
2665         public ActivityManagerService getService() {
2666             return mService;
2667         }
2668     }
2669
2670     @VisibleForTesting
2671     public ActivityManagerService(Injector injector) {
2672         mInjector = injector;
2673         mContext = mInjector.getContext();
2674         mUiContext = null;
2675         GL_ES_VERSION = 0;
2676         mActivityStarter = null;
2677         mAppErrors = null;
2678         mAppOpsService = mInjector.getAppOpsService(null, null);
2679         mBatteryStatsService = null;
2680         mCompatModePackages = null;
2681         mConstants = null;
2682         mGrantFile = null;
2683         mHandler = null;
2684         mHandlerThread = null;
2685         mIntentFirewall = null;
2686         mKeyguardController = null;
2687         mPermissionReviewRequired = false;
2688         mProcessCpuThread = null;
2689         mProcessStats = null;
2690         mProviderMap = null;
2691         mRecentTasks = null;
2692         mServices = null;
2693         mStackSupervisor = null;
2694         mSystemThread = null;
2695         mTaskChangeNotificationController = null;
2696         mUiHandler = injector.getUiHandler(null);
2697         mUserController = null;
2698         mVrController = null;
2699     }
2700
2701     // Note: This method is invoked on the main thread but may need to attach various
2702     // handlers to other threads.  So take care to be explicit about the looper.
2703     public ActivityManagerService(Context systemContext) {
2704         LockGuard.installLock(this, LockGuard.INDEX_ACTIVITY);
2705         mInjector = new Injector();
2706         mContext = systemContext;
2707
2708         mFactoryTest = FactoryTest.getMode();
2709         mSystemThread = ActivityThread.currentActivityThread();
2710         mUiContext = mSystemThread.getSystemUiContext();
2711
2712         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2713
2714         mPermissionReviewRequired = mContext.getResources().getBoolean(
2715                 com.android.internal.R.bool.config_permissionReviewRequired);
2716
2717         mHandlerThread = new ServiceThread(TAG,
2718                 THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2719         mHandlerThread.start();
2720         mHandler = new MainHandler(mHandlerThread.getLooper());
2721         mUiHandler = mInjector.getUiHandler(this);
2722
2723         mConstants = new ActivityManagerConstants(this, mHandler);
2724
2725         /* static; one-time init here */
2726         if (sKillHandler == null) {
2727             sKillThread = new ServiceThread(TAG + ":kill",
2728                     THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2729             sKillThread.start();
2730             sKillHandler = new KillHandler(sKillThread.getLooper());
2731         }
2732
2733         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2734                 "foreground", BROADCAST_FG_TIMEOUT, false);
2735         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2736                 "background", BROADCAST_BG_TIMEOUT, true);
2737         mBroadcastQueues[0] = mFgBroadcastQueue;
2738         mBroadcastQueues[1] = mBgBroadcastQueue;
2739
2740         mServices = new ActiveServices(this);
2741         mProviderMap = new ProviderMap(this);
2742         mAppErrors = new AppErrors(mUiContext, this);
2743
2744         // TODO: Move creation of battery stats service outside of activity manager service.
2745         File dataDir = Environment.getDataDirectory();
2746         File systemDir = new File(dataDir, "system");
2747         systemDir.mkdirs();
2748         mBatteryStatsService = new BatteryStatsService(systemContext, systemDir, mHandler);
2749         mBatteryStatsService.getActiveStatistics().readLocked();
2750         mBatteryStatsService.scheduleWriteToDisk();
2751         mOnBattery = DEBUG_POWER ? true
2752                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2753         mBatteryStatsService.getActiveStatistics().setCallback(this);
2754
2755         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2756
2757         mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
2758         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2759                 new IAppOpsCallback.Stub() {
2760                     @Override public void opChanged(int op, int uid, String packageName) {
2761                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2762                             if (mAppOpsService.checkOperation(op, uid, packageName)
2763                                     != AppOpsManager.MODE_ALLOWED) {
2764                                 runInBackgroundDisabled(uid);
2765                             }
2766                         }
2767                     }
2768                 });
2769
2770         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2771
2772         mUserController = new UserController(this);
2773
2774         mVrController = new VrController(this);
2775
2776         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2777             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2778
2779         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2780             mUseFifoUiScheduling = true;
2781         }
2782
2783         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2784         mTempConfig.setToDefaults();
2785         mTempConfig.setLocales(LocaleList.getDefault());
2786         mConfigurationSeq = mTempConfig.seq = 1;
2787         mStackSupervisor = createStackSupervisor();
2788         mStackSupervisor.onConfigurationChanged(mTempConfig);
2789         mKeyguardController = mStackSupervisor.mKeyguardController;
2790         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2791         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2792         mTaskChangeNotificationController =
2793                 new TaskChangeNotificationController(this, mStackSupervisor, mHandler);
2794         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2795         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2796
2797         mProcessCpuThread = new Thread("CpuTracker") {
2798             @Override
2799             public void run() {
2800                 synchronized (mProcessCpuTracker) {
2801                     mProcessCpuInitLatch.countDown();
2802                     mProcessCpuTracker.init();
2803                 }
2804                 while (true) {
2805                     try {
2806                         try {
2807                             synchronized(this) {
2808                                 final long now = SystemClock.uptimeMillis();
2809                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2810                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2811                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2812                                 //        + ", write delay=" + nextWriteDelay);
2813                                 if (nextWriteDelay < nextCpuDelay) {
2814                                     nextCpuDelay = nextWriteDelay;
2815                                 }
2816                                 if (nextCpuDelay > 0) {
2817                                     mProcessCpuMutexFree.set(true);
2818                                     this.wait(nextCpuDelay);
2819                                 }
2820                             }
2821                         } catch (InterruptedException e) {
2822                         }
2823                         updateCpuStatsNow();
2824                     } catch (Exception e) {
2825                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2826                     }
2827                 }
2828             }
2829         };
2830
2831         Watchdog.getInstance().addMonitor(this);
2832         Watchdog.getInstance().addThread(mHandler);
2833     }
2834
2835     protected ActivityStackSupervisor createStackSupervisor() {
2836         return new ActivityStackSupervisor(this, mHandler.getLooper());
2837     }
2838
2839     public void setSystemServiceManager(SystemServiceManager mgr) {
2840         mSystemServiceManager = mgr;
2841     }
2842
2843     public void setInstaller(Installer installer) {
2844         mInstaller = installer;
2845     }
2846
2847     private void start() {
2848         removeAllProcessGroups();
2849         mProcessCpuThread.start();
2850
2851         mBatteryStatsService.publish();
2852         mAppOpsService.publish(mContext);
2853         Slog.d("AppOps", "AppOpsService published");
2854         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2855         // Wait for the synchronized block started in mProcessCpuThread,
2856         // so that any other acccess to mProcessCpuTracker from main thread
2857         // will be blocked during mProcessCpuTracker initialization.
2858         try {
2859             mProcessCpuInitLatch.await();
2860         } catch (InterruptedException e) {
2861             Slog.wtf(TAG, "Interrupted wait during start", e);
2862             Thread.currentThread().interrupt();
2863             throw new IllegalStateException("Interrupted wait during start");
2864         }
2865     }
2866
2867     void onUserStoppedLocked(int userId) {
2868         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2869     }
2870
2871     public void initPowerManagement() {
2872         mStackSupervisor.initPowerManagement();
2873         mBatteryStatsService.initPowerManagement();
2874         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2875         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2876         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2877         mVoiceWakeLock.setReferenceCounted(false);
2878     }
2879
2880     private ArraySet<String> getBackgroundLaunchBroadcasts() {
2881         if (mBackgroundLaunchBroadcasts == null) {
2882             mBackgroundLaunchBroadcasts = SystemConfig.getInstance().getAllowImplicitBroadcasts();
2883         }
2884         return mBackgroundLaunchBroadcasts;
2885     }
2886
2887     @Override
2888     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2889             throws RemoteException {
2890         if (code == SYSPROPS_TRANSACTION) {
2891             // We need to tell all apps about the system property change.
2892             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2893             synchronized(this) {
2894                 final int NP = mProcessNames.getMap().size();
2895                 for (int ip=0; ip<NP; ip++) {
2896                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2897                     final int NA = apps.size();
2898                     for (int ia=0; ia<NA; ia++) {
2899                         ProcessRecord app = apps.valueAt(ia);
2900                         if (app.thread != null) {
2901                             procs.add(app.thread.asBinder());
2902                         }
2903                     }
2904                 }
2905             }
2906
2907             int N = procs.size();
2908             for (int i=0; i<N; i++) {
2909                 Parcel data2 = Parcel.obtain();
2910                 try {
2911                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null,
2912                             Binder.FLAG_ONEWAY);
2913                 } catch (RemoteException e) {
2914                 }
2915                 data2.recycle();
2916             }
2917         }
2918         try {
2919             return super.onTransact(code, data, reply, flags);
2920         } catch (RuntimeException e) {
2921             // The activity manager only throws security exceptions, so let's
2922             // log all others.
2923             if (!(e instanceof SecurityException)) {
2924                 Slog.wtf(TAG, "Activity Manager Crash."
2925                         + " UID:" + Binder.getCallingUid()
2926                         + " PID:" + Binder.getCallingPid()
2927                         + " TRANS:" + code, e);
2928             }
2929             throw e;
2930         }
2931     }
2932
2933     void updateCpuStats() {
2934         final long now = SystemClock.uptimeMillis();
2935         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2936             return;
2937         }
2938         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2939             synchronized (mProcessCpuThread) {
2940                 mProcessCpuThread.notify();
2941             }
2942         }
2943     }
2944
2945     void updateCpuStatsNow() {
2946         synchronized (mProcessCpuTracker) {
2947             mProcessCpuMutexFree.set(false);
2948             final long now = SystemClock.uptimeMillis();
2949             boolean haveNewCpuStats = false;
2950
2951             if (MONITOR_CPU_USAGE &&
2952                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2953                 mLastCpuTime.set(now);
2954                 mProcessCpuTracker.update();
2955                 if (mProcessCpuTracker.hasGoodLastStats()) {
2956                     haveNewCpuStats = true;
2957                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2958                     //Slog.i(TAG, "Total CPU usage: "
2959                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2960
2961                     // Slog the cpu usage if the property is set.
2962                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2963                         int user = mProcessCpuTracker.getLastUserTime();
2964                         int system = mProcessCpuTracker.getLastSystemTime();
2965                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2966                         int irq = mProcessCpuTracker.getLastIrqTime();
2967                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2968                         int idle = mProcessCpuTracker.getLastIdleTime();
2969
2970                         int total = user + system + iowait + irq + softIrq + idle;
2971                         if (total == 0) total = 1;
2972
2973                         EventLog.writeEvent(EventLogTags.CPU,
2974                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2975                                 (user * 100) / total,
2976                                 (system * 100) / total,
2977                                 (iowait * 100) / total,
2978                                 (irq * 100) / total,
2979                                 (softIrq * 100) / total);
2980                     }
2981                 }
2982             }
2983
2984             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2985             synchronized(bstats) {
2986                 synchronized(mPidsSelfLocked) {
2987                     if (haveNewCpuStats) {
2988                         if (bstats.startAddingCpuLocked()) {
2989                             int totalUTime = 0;
2990                             int totalSTime = 0;
2991                             final int N = mProcessCpuTracker.countStats();
2992                             for (int i=0; i<N; i++) {
2993                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2994                                 if (!st.working) {
2995                                     continue;
2996                                 }
2997                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2998                                 totalUTime += st.rel_utime;
2999                                 totalSTime += st.rel_stime;
3000                                 if (pr != null) {
3001                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
3002                                     if (ps == null || !ps.isActive()) {
3003                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
3004                                                 pr.info.uid, pr.processName);
3005                                     }
3006                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3007                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
3008                                     if (pr.lastCpuTime == 0) {
3009                                         pr.lastCpuTime = pr.curCpuTime;
3010                                     }
3011                                 } else {
3012                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
3013                                     if (ps == null || !ps.isActive()) {
3014                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
3015                                                 bstats.mapUid(st.uid), st.name);
3016                                     }
3017                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
3018                                 }
3019                             }
3020                             final int userTime = mProcessCpuTracker.getLastUserTime();
3021                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
3022                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
3023                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
3024                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
3025                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
3026                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
3027                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
3028                         }
3029                     }
3030                 }
3031
3032                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
3033                     mLastWriteTime = now;
3034                     mBatteryStatsService.scheduleWriteToDisk();
3035                 }
3036             }
3037         }
3038     }
3039
3040     @Override
3041     public void batteryNeedsCpuUpdate() {
3042         updateCpuStatsNow();
3043     }
3044
3045     @Override
3046     public void batteryPowerChanged(boolean onBattery) {
3047         // When plugging in, update the CPU stats first before changing
3048         // the plug state.
3049         updateCpuStatsNow();
3050         synchronized (this) {
3051             synchronized(mPidsSelfLocked) {
3052                 mOnBattery = DEBUG_POWER ? true : onBattery;
3053             }
3054         }
3055     }
3056
3057     @Override
3058     public void batterySendBroadcast(Intent intent) {
3059         synchronized (this) {
3060             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
3061                     AppOpsManager.OP_NONE, null, false, false,
3062                     -1, SYSTEM_UID, UserHandle.USER_ALL);
3063         }
3064     }
3065
3066     /**
3067      * Initialize the application bind args. These are passed to each
3068      * process when the bindApplication() IPC is sent to the process. They're
3069      * lazily setup to make sure the services are running when they're asked for.
3070      */
3071     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
3072         // Isolated processes won't get this optimization, so that we don't
3073         // violate the rules about which services they have access to.
3074         if (isolated) {
3075             if (mIsolatedAppBindArgs == null) {
3076                 mIsolatedAppBindArgs = new HashMap<>();
3077                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
3078             }
3079             return mIsolatedAppBindArgs;
3080         }
3081
3082         if (mAppBindArgs == null) {
3083             mAppBindArgs = new HashMap<>();
3084
3085             // Setup the application init args
3086             mAppBindArgs.put("package", ServiceManager.getService("package"));
3087             mAppBindArgs.put("window", ServiceManager.getService("window"));
3088             mAppBindArgs.put(Context.ALARM_SERVICE,
3089                     ServiceManager.getService(Context.ALARM_SERVICE));
3090         }
3091         return mAppBindArgs;
3092     }
3093
3094     /**
3095      * Update AMS states when an activity is resumed. This should only be called by
3096      * {@link ActivityStack#setResumedActivityLocked} when an activity is resumed.
3097      */
3098     void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
3099         final TaskRecord task = r.getTask();
3100         if (task.isApplicationTask()) {
3101             if (mCurAppTimeTracker != r.appTimeTracker) {
3102                 // We are switching app tracking.  Complete the current one.
3103                 if (mCurAppTimeTracker != null) {
3104                     mCurAppTimeTracker.stop();
3105                     mHandler.obtainMessage(
3106                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
3107                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3108                     mCurAppTimeTracker = null;
3109                 }
3110                 if (r.appTimeTracker != null) {
3111                     mCurAppTimeTracker = r.appTimeTracker;
3112                     startTimeTrackingFocusedActivityLocked();
3113                 }
3114             } else {
3115                 startTimeTrackingFocusedActivityLocked();
3116             }
3117         } else {
3118             r.appTimeTracker = null;
3119         }
3120         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3121         // TODO: Probably not, because we don't want to resume voice on switching
3122         // back to this activity
3123         if (task.voiceInteractor != null) {
3124             startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
3125         } else {
3126             finishRunningVoiceLocked();
3127
3128             if (mLastResumedActivity != null) {
3129                 final IVoiceInteractionSession session;
3130
3131                 final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
3132                 if (lastResumedActivityTask != null
3133                         && lastResumedActivityTask.voiceSession != null) {
3134                     session = lastResumedActivityTask.voiceSession;
3135                 } else {
3136                     session = mLastResumedActivity.voiceSession;
3137                 }
3138
3139                 if (session != null) {
3140                     // We had been in a voice interaction session, but now focused has
3141                     // move to something different.  Just finish the session, we can't
3142                     // return to it and retain the proper state and synchronization with
3143                     // the voice interaction service.
3144                     finishVoiceTask(session);
3145                 }
3146             }
3147         }
3148
3149         if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
3150             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3151             mHandler.obtainMessage(
3152                     FOREGROUND_PROFILE_CHANGED_MSG, r.userId, 0).sendToTarget();
3153         }
3154         mLastResumedActivity = r;
3155
3156         mWindowManager.setFocusedApp(r.appToken, true);
3157
3158         applyUpdateLockStateLocked(r);
3159         applyUpdateVrModeLocked(r);
3160
3161         EventLogTags.writeAmSetResumedActivity(
3162                 r == null ? -1 : r.userId,
3163                 r == null ? "NULL" : r.shortComponentName,
3164                 reason);
3165     }
3166
3167     @Override
3168     public void setFocusedStack(int stackId) {
3169         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3170         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3171         final long callingId = Binder.clearCallingIdentity();
3172         try {
3173             synchronized (this) {
3174                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3175                 if (stack == null) {
3176                     return;
3177                 }
3178                 final ActivityRecord r = stack.topRunningActivityLocked();
3179                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedStack")) {
3180                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3181                 }
3182             }
3183         } finally {
3184             Binder.restoreCallingIdentity(callingId);
3185         }
3186     }
3187
3188     @Override
3189     public void setFocusedTask(int taskId) {
3190         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3191         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3192         final long callingId = Binder.clearCallingIdentity();
3193         try {
3194             synchronized (this) {
3195                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3196                 if (task == null) {
3197                     return;
3198                 }
3199                 final ActivityRecord r = task.topRunningActivityLocked();
3200                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(r, "setFocusedTask")) {
3201                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3202                 }
3203             }
3204         } finally {
3205             Binder.restoreCallingIdentity(callingId);
3206         }
3207     }
3208
3209     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3210     @Override
3211     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3212         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3213         mTaskChangeNotificationController.registerTaskStackListener(listener);
3214     }
3215
3216     /**
3217      * Unregister a task stack listener so that it stops receiving callbacks.
3218      */
3219     @Override
3220     public void unregisterTaskStackListener(ITaskStackListener listener) throws RemoteException {
3221          enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "unregisterTaskStackListener()");
3222          mTaskChangeNotificationController.unregisterTaskStackListener(listener);
3223      }
3224
3225     @Override
3226     public void notifyActivityDrawn(IBinder token) {
3227         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3228         synchronized (this) {
3229             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3230             if (r != null) {
3231                 r.getStack().notifyActivityDrawnLocked(r);
3232             }
3233         }
3234     }
3235
3236     final void applyUpdateLockStateLocked(ActivityRecord r) {
3237         // Modifications to the UpdateLock state are done on our handler, outside
3238         // the activity manager's locks.  The new state is determined based on the
3239         // state *now* of the relevant activity record.  The object is passed to
3240         // the handler solely for logging detail, not to be consulted/modified.
3241         final boolean nextState = r != null && r.immersive;
3242         mHandler.sendMessage(
3243                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3244     }
3245
3246     final void applyUpdateVrModeLocked(ActivityRecord r) {
3247         // VR apps are expected to run in a main display. If an app is turning on VR for
3248         // itself, but lives in a dynamic stack, then make sure that it is moved to the main
3249         // fullscreen stack before enabling VR Mode.
3250         // TODO: The goal of this code is to keep the VR app on the main display. When the
3251         // stack implementation changes in the future, keep in mind that the use of the fullscreen
3252         // stack is a means to move the activity to the main display and a moveActivityToDisplay()
3253         // option would be a better choice here.
3254         if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
3255             Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
3256                     + " to main stack for VR");
3257             moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
3258         }
3259         mHandler.sendMessage(
3260                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3261     }
3262
3263     private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3264         mHandler.sendMessage(
3265                 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3266     }
3267
3268     private void notifyVrManagerOfSleepState(boolean isSleeping) {
3269         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3270         if (vrService == null) {
3271             return;
3272         }
3273         vrService.onSleepStateChanged(isSleeping);
3274     }
3275
3276     private void sendNotifyVrManagerOfKeyguardState(boolean isShowing) {
3277         mHandler.sendMessage(
3278                 mHandler.obtainMessage(NOTIFY_VR_KEYGUARD_MSG, isShowing ? 1 : 0, 0));
3279     }
3280
3281     private void notifyVrManagerOfKeyguardState(boolean isShowing) {
3282         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3283         if (vrService == null) {
3284             return;
3285         }
3286         vrService.onKeyguardStateChanged(isShowing);
3287     }
3288
3289     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3290         Message msg = Message.obtain();
3291         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3292         msg.obj = r.getTask().askedCompatMode ? null : r;
3293         mUiHandler.sendMessage(msg);
3294     }
3295
3296     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3297         final Configuration globalConfig = getGlobalConfiguration();
3298         if (globalConfig.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3299                 && r.appInfo.requiresSmallestWidthDp > globalConfig.smallestScreenWidthDp) {
3300             final Message msg = Message.obtain();
3301             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3302             msg.obj = r;
3303             mUiHandler.sendMessage(msg);
3304         }
3305     }
3306
3307     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3308             String what, Object obj, ProcessRecord srcApp) {
3309         app.lastActivityTime = now;
3310
3311         if (app.activities.size() > 0) {
3312             // Don't want to touch dependent processes that are hosting activities.
3313             return index;
3314         }
3315
3316         int lrui = mLruProcesses.lastIndexOf(app);
3317         if (lrui < 0) {
3318             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3319                     + what + " " + obj + " from " + srcApp);
3320             return index;
3321         }
3322
3323         if (lrui >= index) {
3324             // Don't want to cause this to move dependent processes *back* in the
3325             // list as if they were less frequently used.
3326             return index;
3327         }
3328
3329         if (lrui >= mLruProcessActivityStart) {
3330             // Don't want to touch dependent processes that are hosting activities.
3331             return index;
3332         }
3333
3334         mLruProcesses.remove(lrui);
3335         if (index > 0) {
3336             index--;
3337         }
3338         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3339                 + " in LRU list: " + app);
3340         mLruProcesses.add(index, app);
3341         return index;
3342     }
3343
3344     static void killProcessGroup(int uid, int pid) {
3345         if (sKillHandler != null) {
3346             sKillHandler.sendMessage(
3347                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3348         } else {
3349             Slog.w(TAG, "Asked to kill process group before system bringup!");
3350             Process.killProcessGroup(uid, pid);
3351         }
3352     }
3353
3354     final void removeLruProcessLocked(ProcessRecord app) {
3355         int lrui = mLruProcesses.lastIndexOf(app);
3356         if (lrui >= 0) {
3357             if (!app.killed) {
3358                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3359                 killProcessQuiet(app.pid);
3360                 killProcessGroup(app.uid, app.pid);
3361             }
3362             if (lrui <= mLruProcessActivityStart) {
3363                 mLruProcessActivityStart--;
3364             }
3365             if (lrui <= mLruProcessServiceStart) {
3366                 mLruProcessServiceStart--;
3367             }
3368             mLruProcesses.remove(lrui);
3369         }
3370     }
3371
3372     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3373             ProcessRecord client) {
3374         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3375                 || app.treatLikeActivity;
3376         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3377         if (!activityChange && hasActivity) {
3378             // The process has activities, so we are only allowing activity-based adjustments
3379             // to move it.  It should be kept in the front of the list with other
3380             // processes that have activities, and we don't want those to change their
3381             // order except due to activity operations.
3382             return;
3383         }
3384
3385         mLruSeq++;
3386         final long now = SystemClock.uptimeMillis();
3387         app.lastActivityTime = now;
3388
3389         // First a quick reject: if the app is already at the position we will
3390         // put it, then there is nothing to do.
3391         if (hasActivity) {
3392             final int N = mLruProcesses.size();
3393             if (N > 0 && mLruProcesses.get(N-1) == app) {
3394                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3395                 return;
3396             }
3397         } else {
3398             if (mLruProcessServiceStart > 0
3399                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3400                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3401                 return;
3402             }
3403         }
3404
3405         int lrui = mLruProcesses.lastIndexOf(app);
3406
3407         if (app.persistent && lrui >= 0) {
3408             // We don't care about the position of persistent processes, as long as
3409             // they are in the list.
3410             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3411             return;
3412         }
3413
3414         /* In progress: compute new position first, so we can avoid doing work
3415            if the process is not actually going to move.  Not yet working.
3416         int addIndex;
3417         int nextIndex;
3418         boolean inActivity = false, inService = false;
3419         if (hasActivity) {
3420             // Process has activities, put it at the very tipsy-top.
3421             addIndex = mLruProcesses.size();
3422             nextIndex = mLruProcessServiceStart;
3423             inActivity = true;
3424         } else if (hasService) {
3425             // Process has services, put it at the top of the service list.
3426             addIndex = mLruProcessActivityStart;
3427             nextIndex = mLruProcessServiceStart;
3428             inActivity = true;
3429             inService = true;
3430         } else  {
3431             // Process not otherwise of interest, it goes to the top of the non-service area.
3432             addIndex = mLruProcessServiceStart;
3433             if (client != null) {
3434                 int clientIndex = mLruProcesses.lastIndexOf(client);
3435                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3436                         + app);
3437                 if (clientIndex >= 0 && addIndex > clientIndex) {
3438                     addIndex = clientIndex;
3439                 }
3440             }
3441             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3442         }
3443
3444         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3445                 + mLruProcessActivityStart + "): " + app);
3446         */
3447
3448         if (lrui >= 0) {
3449             if (lrui < mLruProcessActivityStart) {
3450                 mLruProcessActivityStart--;
3451             }
3452             if (lrui < mLruProcessServiceStart) {
3453                 mLruProcessServiceStart--;
3454             }
3455             /*
3456             if (addIndex > lrui) {
3457                 addIndex--;
3458             }
3459             if (nextIndex > lrui) {
3460                 nextIndex--;
3461             }
3462             */
3463             mLruProcesses.remove(lrui);
3464         }
3465
3466         /*
3467         mLruProcesses.add(addIndex, app);
3468         if (inActivity) {
3469             mLruProcessActivityStart++;
3470         }
3471         if (inService) {
3472             mLruProcessActivityStart++;
3473         }
3474         */
3475
3476         int nextIndex;
3477         if (hasActivity) {
3478             final int N = mLruProcesses.size();
3479             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3480                 // Process doesn't have activities, but has clients with
3481                 // activities...  move it up, but one below the top (the top
3482                 // should always have a real activity).
3483                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3484                         "Adding to second-top of LRU activity list: " + app);
3485                 mLruProcesses.add(N - 1, app);
3486                 // To keep it from spamming the LRU list (by making a bunch of clients),
3487                 // we will push down any other entries owned by the app.
3488                 final int uid = app.info.uid;
3489                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3490                     ProcessRecord subProc = mLruProcesses.get(i);
3491                     if (subProc.info.uid == uid) {
3492                         // We want to push this one down the list.  If the process after
3493                         // it is for the same uid, however, don't do so, because we don't
3494                         // want them internally to be re-ordered.
3495                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3496                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3497                                     "Pushing uid " + uid + " swapping at " + i + ": "
3498                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3499                             ProcessRecord tmp = mLruProcesses.get(i);
3500                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3501                             mLruProcesses.set(i - 1, tmp);
3502                             i--;
3503                         }
3504                     } else {
3505                         // A gap, we can stop here.
3506                         break;
3507                     }
3508                 }
3509             } else {
3510                 // Process has activities, put it at the very tipsy-top.
3511                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3512                 mLruProcesses.add(app);
3513             }
3514             nextIndex = mLruProcessServiceStart;
3515         } else if (hasService) {
3516             // Process has services, put it at the top of the service list.
3517             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3518             mLruProcesses.add(mLruProcessActivityStart, app);
3519             nextIndex = mLruProcessServiceStart;
3520             mLruProcessActivityStart++;
3521         } else  {
3522             // Process not otherwise of interest, it goes to the top of the non-service area.
3523             int index = mLruProcessServiceStart;
3524             if (client != null) {
3525                 // If there is a client, don't allow the process to be moved up higher
3526                 // in the list than that client.
3527                 int clientIndex = mLruProcesses.lastIndexOf(client);
3528                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3529                         + " when updating " + app);
3530                 if (clientIndex <= lrui) {
3531                     // Don't allow the client index restriction to push it down farther in the
3532                     // list than it already is.
3533                     clientIndex = lrui;
3534                 }
3535                 if (clientIndex >= 0 && index > clientIndex) {
3536                     index = clientIndex;
3537                 }
3538             }
3539             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3540             mLruProcesses.add(index, app);
3541             nextIndex = index-1;
3542             mLruProcessActivityStart++;
3543             mLruProcessServiceStart++;
3544         }
3545
3546         // If the app is currently using a content provider or service,
3547         // bump those processes as well.
3548         for (int j=app.connections.size()-1; j>=0; j--) {
3549             ConnectionRecord cr = app.connections.valueAt(j);
3550             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3551                     && cr.binding.service.app != null
3552                     && cr.binding.service.app.lruSeq != mLruSeq
3553                     && !cr.binding.service.app.persistent) {
3554                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3555                         "service connection", cr, app);
3556             }
3557         }
3558         for (int j=app.conProviders.size()-1; j>=0; j--) {
3559             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3560             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3561                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3562                         "provider reference", cpr, app);
3563             }
3564         }
3565     }
3566
3567     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3568         if (uid == SYSTEM_UID) {
3569             // The system gets to run in any process.  If there are multiple
3570             // processes with the same uid, just pick the first (this
3571             // should never happen).
3572             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3573             if (procs == null) return null;
3574             final int procCount = procs.size();
3575             for (int i = 0; i < procCount; i++) {
3576                 final int procUid = procs.keyAt(i);
3577                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3578                     // Don't use an app process or different user process for system component.
3579                     continue;
3580                 }
3581                 return procs.valueAt(i);
3582             }
3583         }
3584         ProcessRecord proc = mProcessNames.get(processName, uid);
3585         if (false && proc != null && !keepIfLarge
3586                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3587                 && proc.lastCachedPss >= 4000) {
3588             // Turn this condition on to cause killing to happen regularly, for testing.
3589             if (proc.baseProcessTracker != null) {
3590                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3591             }
3592             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3593         } else if (proc != null && !keepIfLarge
3594                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3595                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3596             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3597             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3598                 if (proc.baseProcessTracker != null) {
3599                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3600                 }
3601                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3602             }
3603         }
3604         return proc;
3605     }
3606
3607     void notifyPackageUse(String packageName, int reason) {
3608         synchronized(this) {
3609             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3610         }
3611     }
3612
3613     boolean isNextTransitionForward() {
3614         int transit = mWindowManager.getPendingAppTransition();
3615         return transit == TRANSIT_ACTIVITY_OPEN
3616                 || transit == TRANSIT_TASK_OPEN
3617                 || transit == TRANSIT_TASK_TO_FRONT;
3618     }
3619
3620     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3621             String processName, String abiOverride, int uid, Runnable crashHandler) {
3622         synchronized(this) {
3623             ApplicationInfo info = new ApplicationInfo();
3624             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3625             // For isolated processes, the former contains the parent's uid and the latter the
3626             // actual uid of the isolated process.
3627             // In the special case introduced by this method (which is, starting an isolated
3628             // process directly from the SystemServer without an actual parent app process) the
3629             // closest thing to a parent's uid is SYSTEM_UID.
3630             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3631             // the |isolated| logic in the ProcessRecord constructor.
3632             info.uid = SYSTEM_UID;
3633             info.processName = processName;
3634             info.className = entryPoint;
3635             info.packageName = "android";
3636             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3637             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3638                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3639                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3640                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3641                     crashHandler);
3642             return proc != null ? proc.pid : 0;
3643         }
3644     }
3645
3646     final ProcessRecord startProcessLocked(String processName,
3647             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3648             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3649             boolean isolated, boolean keepIfLarge) {
3650         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3651                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3652                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3653                 null /* crashHandler */);
3654     }
3655
3656     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3657             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3658             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3659             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3660         long startTime = SystemClock.elapsedRealtime();
3661         ProcessRecord app;
3662         if (!isolated) {
3663             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3664             checkTime(startTime, "startProcess: after getProcessRecord");
3665
3666             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3667                 // If we are in the background, then check to see if this process
3668                 // is bad.  If so, we will just silently fail.
3669                 if (mAppErrors.isBadProcessLocked(info)) {
3670                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3671                             + "/" + info.processName);
3672                     return null;
3673                 }
3674             } else {
3675                 // When the user is explicitly starting a process, then clear its
3676                 // crash count so that we won't make it bad until they see at
3677                 // least one crash dialog again, and make the process good again
3678                 // if it had been bad.
3679                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3680                         + "/" + info.processName);
3681                 mAppErrors.resetProcessCrashTimeLocked(info);
3682                 if (mAppErrors.isBadProcessLocked(info)) {
3683                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3684                             UserHandle.getUserId(info.uid), info.uid,
3685                             info.processName);
3686                     mAppErrors.clearBadProcessLocked(info);
3687                     if (app != null) {
3688                         app.bad = false;
3689                     }
3690                 }
3691             }
3692         } else {
3693             // If this is an isolated process, it can't re-use an existing process.
3694             app = null;
3695         }
3696
3697         // We don't have to do anything more if:
3698         // (1) There is an existing application record; and
3699         // (2) The caller doesn't think it is dead, OR there is no thread
3700         //     object attached to it so we know it couldn't have crashed; and
3701         // (3) There is a pid assigned to it, so it is either starting or
3702         //     already running.
3703         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3704                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3705                 + " thread=" + (app != null ? app.thread : null)
3706                 + " pid=" + (app != null ? app.pid : -1));
3707         if (app != null && app.pid > 0) {
3708             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3709                 // We already have the app running, or are waiting for it to
3710                 // come up (we have a pid but not yet its thread), so keep it.
3711                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3712                 // If this is a new package in the process, add the package to the list
3713                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3714                 checkTime(startTime, "startProcess: done, added package to proc");
3715                 return app;
3716             }
3717
3718             // An application record is attached to a previous process,
3719             // clean it up now.
3720             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3721             checkTime(startTime, "startProcess: bad proc running, killing");
3722             killProcessGroup(app.uid, app.pid);
3723             handleAppDiedLocked(app, true, true);
3724             checkTime(startTime, "startProcess: done killing old proc");
3725         }
3726
3727         String hostingNameStr = hostingName != null
3728                 ? hostingName.flattenToShortString() : null;
3729
3730         if (app == null) {
3731             checkTime(startTime, "startProcess: creating new process record");
3732             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3733             if (app == null) {
3734                 Slog.w(TAG, "Failed making new process record for "
3735                         + processName + "/" + info.uid + " isolated=" + isolated);
3736                 return null;
3737             }
3738             app.crashHandler = crashHandler;
3739             checkTime(startTime, "startProcess: done creating new process record");
3740         } else {
3741             // If this is a new package in the process, add the package to the list
3742             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3743             checkTime(startTime, "startProcess: added package to existing proc");
3744         }
3745
3746         // If the system is not ready yet, then hold off on starting this
3747         // process until it is.
3748         if (!mProcessesReady
3749                 && !isAllowedWhileBooting(info)
3750                 && !allowWhileBooting) {
3751             if (!mProcessesOnHold.contains(app)) {
3752                 mProcessesOnHold.add(app);
3753             }
3754             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3755                     "System not ready, putting on hold: " + app);
3756             checkTime(startTime, "startProcess: returning with proc on hold");
3757             return app;
3758         }
3759
3760         checkTime(startTime, "startProcess: stepping in to startProcess");
3761         startProcessLocked(
3762                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3763         checkTime(startTime, "startProcess: done starting proc!");
3764         return (app.pid != 0) ? app : null;
3765     }
3766
3767     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3768         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3769     }
3770
3771     private final void startProcessLocked(ProcessRecord app,
3772             String hostingType, String hostingNameStr) {
3773         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3774                 null /* entryPoint */, null /* entryPointArgs */);
3775     }
3776
3777     private final void startProcessLocked(ProcessRecord app, String hostingType,
3778             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3779         long startTime = SystemClock.elapsedRealtime();
3780         if (app.pid > 0 && app.pid != MY_PID) {
3781             checkTime(startTime, "startProcess: removing from pids map");
3782             synchronized (mPidsSelfLocked) {
3783                 mPidsSelfLocked.remove(app.pid);
3784                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3785             }
3786             checkTime(startTime, "startProcess: done removing from pids map");
3787             app.setPid(0);
3788         }
3789
3790         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3791                 "startProcessLocked removing on hold: " + app);
3792         mProcessesOnHold.remove(app);
3793
3794         checkTime(startTime, "startProcess: starting to update cpu stats");
3795         updateCpuStats();
3796         checkTime(startTime, "startProcess: done updating cpu stats");
3797
3798         try {
3799             try {
3800                 final int userId = UserHandle.getUserId(app.uid);
3801                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3802             } catch (RemoteException e) {
3803                 throw e.rethrowAsRuntimeException();
3804             }
3805
3806             int uid = app.uid;
3807             int[] gids = null;
3808             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3809             if (!app.isolated) {
3810                 int[] permGids = null;
3811                 try {
3812                     checkTime(startTime, "startProcess: getting gids from package manager");
3813                     final IPackageManager pm = AppGlobals.getPackageManager();
3814                     permGids = pm.getPackageGids(app.info.packageName,
3815                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3816                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3817                             StorageManagerInternal.class);
3818                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3819                             app.info.packageName);
3820                 } catch (RemoteException e) {
3821                     throw e.rethrowAsRuntimeException();
3822                 }
3823
3824                 /*
3825                  * Add shared application and profile GIDs so applications can share some
3826                  * resources like shared libraries and access user-wide resources
3827                  */
3828                 if (ArrayUtils.isEmpty(permGids)) {
3829                     gids = new int[3];
3830                 } else {
3831                     gids = new int[permGids.length + 3];
3832                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3833                 }
3834                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3835                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3836                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3837             }
3838             checkTime(startTime, "startProcess: building args");
3839             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3840                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3841                         && mTopComponent != null
3842                         && app.processName.equals(mTopComponent.getPackageName())) {
3843                     uid = 0;
3844                 }
3845                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3846                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3847                     uid = 0;
3848                 }
3849             }
3850             int debugFlags = 0;
3851             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3852                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3853                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3854                 // Also turn on CheckJNI for debuggable apps. It's quite
3855                 // awkward to turn on otherwise.
3856                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3857             }
3858             // Run the app in safe mode if its manifest requests so or the
3859             // system is booted in safe mode.
3860             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3861                 mSafeMode == true) {
3862                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3863             }
3864             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3865                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3866             }
3867             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3868             if ("true".equals(genDebugInfoProperty)) {
3869                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3870             }
3871             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3872                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3873             }
3874             if ("1".equals(SystemProperties.get("debug.assert"))) {
3875                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3876             }
3877             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3878                 // Enable all debug flags required by the native debugger.
3879                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3880                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3881                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3882                 mNativeDebuggingApp = null;
3883             }
3884
3885             String invokeWith = null;
3886             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3887                 // Debuggable apps may include a wrapper script with their library directory.
3888                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3889                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3890                 try {
3891                     if (new File(wrapperFileName).exists()) {
3892                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3893                     }
3894                 } finally {
3895                     StrictMode.setThreadPolicy(oldPolicy);
3896                 }
3897             }
3898
3899             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3900             if (requiredAbi == null) {
3901                 requiredAbi = Build.SUPPORTED_ABIS[0];
3902             }
3903
3904             String instructionSet = null;
3905             if (app.info.primaryCpuAbi != null) {
3906                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3907             }
3908
3909             app.gids = gids;
3910             app.requiredAbi = requiredAbi;
3911             app.instructionSet = instructionSet;
3912
3913             // the per-user SELinux context must be set
3914             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3915                 Slog.wtf(TAG, "SELinux tag not defined",
3916                         new IllegalStateException("SELinux tag not defined for "
3917                         + app.info.packageName + " (uid " + app.uid + ")"));
3918             }
3919             final String seInfo = app.info.seInfo
3920                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3921             // Start the process.  It will either succeed and return a result containing
3922             // the PID of the new process, or else throw a RuntimeException.
3923             boolean isActivityProcess = (entryPoint == null);
3924             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3925             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3926                     app.processName);
3927             checkTime(startTime, "startProcess: asking zygote to start proc");
3928             ProcessStartResult startResult;
3929             if (hostingType.equals("webview_service")) {
3930                 startResult = startWebView(entryPoint,
3931                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3932                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3933                         app.info.dataDir, null, entryPointArgs);
3934             } else {
3935                 startResult = Process.start(entryPoint,
3936                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3937                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3938                         app.info.dataDir, invokeWith, entryPointArgs);
3939             }
3940             checkTime(startTime, "startProcess: returned from zygote!");
3941             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3942
3943             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3944             checkTime(startTime, "startProcess: done updating battery stats");
3945
3946             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3947                     UserHandle.getUserId(uid), startResult.pid, uid,
3948                     app.processName, hostingType,
3949                     hostingNameStr != null ? hostingNameStr : "");
3950
3951             try {
3952                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3953                         seInfo, app.info.sourceDir, startResult.pid);
3954             } catch (RemoteException ex) {
3955                 // Ignore
3956             }
3957
3958             if (app.persistent) {
3959                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3960             }
3961
3962             checkTime(startTime, "startProcess: building log message");
3963             StringBuilder buf = mStringBuilder;
3964             buf.setLength(0);
3965             buf.append("Start proc ");
3966             buf.append(startResult.pid);
3967             buf.append(':');
3968             buf.append(app.processName);
3969             buf.append('/');
3970             UserHandle.formatUid(buf, uid);
3971             if (!isActivityProcess) {
3972                 buf.append(" [");
3973                 buf.append(entryPoint);
3974                 buf.append("]");
3975             }
3976             buf.append(" for ");
3977             buf.append(hostingType);
3978             if (hostingNameStr != null) {
3979                 buf.append(" ");
3980                 buf.append(hostingNameStr);
3981             }
3982             Slog.i(TAG, buf.toString());
3983             app.setPid(startResult.pid);
3984             app.usingWrapper = startResult.usingWrapper;
3985             app.removed = false;
3986             app.killed = false;
3987             app.killedByAm = false;
3988             checkTime(startTime, "startProcess: starting to update pids map");
3989             ProcessRecord oldApp;
3990             synchronized (mPidsSelfLocked) {
3991                 oldApp = mPidsSelfLocked.get(startResult.pid);
3992             }
3993             // If there is already an app occupying that pid that hasn't been cleaned up
3994             if (oldApp != null && !app.isolated) {
3995                 // Clean up anything relating to this pid first
3996                 Slog.w(TAG, "Reusing pid " + startResult.pid
3997                         + " while app is still mapped to it");
3998                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3999                         true /*replacingPid*/);
4000             }
4001             synchronized (mPidsSelfLocked) {
4002                 this.mPidsSelfLocked.put(startResult.pid, app);
4003                 if (isActivityProcess) {
4004                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4005                     msg.obj = app;
4006                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4007                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4008                 }
4009             }
4010             checkTime(startTime, "startProcess: done updating pids map");
4011         } catch (RuntimeException e) {
4012             Slog.e(TAG, "Failure starting process " + app.processName, e);
4013
4014             // Something went very wrong while trying to start this process; one
4015             // common case is when the package is frozen due to an active
4016             // upgrade. To recover, clean up any active bookkeeping related to
4017             // starting this process. (We already invoked this method once when
4018             // the package was initially frozen through KILL_APPLICATION_MSG, so
4019             // it doesn't hurt to use it again.)
4020             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4021                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4022         }
4023     }
4024
4025     void updateUsageStats(ActivityRecord component, boolean resumed) {
4026         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4027                 "updateUsageStats: comp=" + component + "res=" + resumed);
4028         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4029         if (resumed) {
4030             if (mUsageStatsService != null) {
4031                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4032                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4033             }
4034             synchronized (stats) {
4035                 stats.noteActivityResumedLocked(component.app.uid);
4036             }
4037         } else {
4038             if (mUsageStatsService != null) {
4039                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4040                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4041             }
4042             synchronized (stats) {
4043                 stats.noteActivityPausedLocked(component.app.uid);
4044             }
4045         }
4046     }
4047
4048     Intent getHomeIntent() {
4049         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4050         intent.setComponent(mTopComponent);
4051         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4052         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4053             intent.addCategory(Intent.CATEGORY_HOME);
4054         }
4055         return intent;
4056     }
4057
4058     boolean startHomeActivityLocked(int userId, String reason) {
4059         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4060                 && mTopAction == null) {
4061             // We are running in factory test mode, but unable to find
4062             // the factory test app, so just sit around displaying the
4063             // error message and don't try to start anything.
4064             return false;
4065         }
4066         Intent intent = getHomeIntent();
4067         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4068         if (aInfo != null) {
4069             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4070             // Don't do this if the home app is currently being
4071             // instrumented.
4072             aInfo = new ActivityInfo(aInfo);
4073             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4074             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4075                     aInfo.applicationInfo.uid, true);
4076             if (app == null || app.instr == null) {
4077                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4078                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4079                 // For ANR debugging to verify if the user activity is the one that actually
4080                 // launched.
4081                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4082                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4083             }
4084         } else {
4085             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4086         }
4087
4088         return true;
4089     }
4090
4091     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4092         ActivityInfo ai = null;
4093         ComponentName comp = intent.getComponent();
4094         try {
4095             if (comp != null) {
4096                 // Factory test.
4097                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4098             } else {
4099                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4100                         intent,
4101                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4102                         flags, userId);
4103
4104                 if (info != null) {
4105                     ai = info.activityInfo;
4106                 }
4107             }
4108         } catch (RemoteException e) {
4109             // ignore
4110         }
4111
4112         return ai;
4113     }
4114
4115     /**
4116      * Starts the "new version setup screen" if appropriate.
4117      */
4118     void startSetupActivityLocked() {
4119         // Only do this once per boot.
4120         if (mCheckedForSetup) {
4121             return;
4122         }
4123
4124         // We will show this screen if the current one is a different
4125         // version than the last one shown, and we are not running in
4126         // low-level factory test mode.
4127         final ContentResolver resolver = mContext.getContentResolver();
4128         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4129                 Settings.Global.getInt(resolver,
4130                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4131             mCheckedForSetup = true;
4132
4133             // See if we should be showing the platform update setup UI.
4134             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4135             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4136                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4137             if (!ris.isEmpty()) {
4138                 final ResolveInfo ri = ris.get(0);
4139                 String vers = ri.activityInfo.metaData != null
4140                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4141                         : null;
4142                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4143                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4144                             Intent.METADATA_SETUP_VERSION);
4145                 }
4146                 String lastVers = Settings.Secure.getString(
4147                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4148                 if (vers != null && !vers.equals(lastVers)) {
4149                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4150                     intent.setComponent(new ComponentName(
4151                             ri.activityInfo.packageName, ri.activityInfo.name));
4152                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4153                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4154                             null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4155                 }
4156             }
4157         }
4158     }
4159
4160     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4161         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4162     }
4163
4164     void enforceNotIsolatedCaller(String caller) {
4165         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4166             throw new SecurityException("Isolated process not allowed to call " + caller);
4167         }
4168     }
4169
4170     void enforceShellRestriction(String restriction, int userHandle) {
4171         if (Binder.getCallingUid() == SHELL_UID) {
4172             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4173                 throw new SecurityException("Shell does not have permission to access user "
4174                         + userHandle);
4175             }
4176         }
4177     }
4178
4179     @Override
4180     public int getFrontActivityScreenCompatMode() {
4181         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4182         synchronized (this) {
4183             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4184         }
4185     }
4186
4187     @Override
4188     public void setFrontActivityScreenCompatMode(int mode) {
4189         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4190                 "setFrontActivityScreenCompatMode");
4191         synchronized (this) {
4192             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4193         }
4194     }
4195
4196     @Override
4197     public int getPackageScreenCompatMode(String packageName) {
4198         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4199         synchronized (this) {
4200             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4201         }
4202     }
4203
4204     @Override
4205     public void setPackageScreenCompatMode(String packageName, int mode) {
4206         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4207                 "setPackageScreenCompatMode");
4208         synchronized (this) {
4209             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4210         }
4211     }
4212
4213     @Override
4214     public boolean getPackageAskScreenCompat(String packageName) {
4215         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4216         synchronized (this) {
4217             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4218         }
4219     }
4220
4221     @Override
4222     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4223         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4224                 "setPackageAskScreenCompat");
4225         synchronized (this) {
4226             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4227         }
4228     }
4229
4230     private boolean hasUsageStatsPermission(String callingPackage) {
4231         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4232                 Binder.getCallingUid(), callingPackage);
4233         if (mode == AppOpsManager.MODE_DEFAULT) {
4234             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4235                     == PackageManager.PERMISSION_GRANTED;
4236         }
4237         return mode == AppOpsManager.MODE_ALLOWED;
4238     }
4239
4240     @Override
4241     public int getPackageProcessState(String packageName, String callingPackage) {
4242         if (!hasUsageStatsPermission(callingPackage)) {
4243             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4244                     "getPackageProcessState");
4245         }
4246
4247         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4248         synchronized (this) {
4249             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4250                 final ProcessRecord proc = mLruProcesses.get(i);
4251                 if (procState > proc.setProcState) {
4252                     if (proc.pkgList.containsKey(packageName) ||
4253                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4254                         procState = proc.setProcState;
4255                     }
4256                 }
4257             }
4258         }
4259         return procState;
4260     }
4261
4262     @Override
4263     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4264             throws RemoteException {
4265         synchronized (this) {
4266             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4267             if (app == null) {
4268                 throw new IllegalArgumentException("Unknown process: " + process);
4269             }
4270             if (app.thread == null) {
4271                 throw new IllegalArgumentException("Process has no app thread");
4272             }
4273             if (app.trimMemoryLevel >= level) {
4274                 throw new IllegalArgumentException(
4275                         "Unable to set a higher trim level than current level");
4276             }
4277             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4278                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4279                 throw new IllegalArgumentException("Unable to set a background trim level "
4280                     + "on a foreground process");
4281             }
4282             app.thread.scheduleTrimMemory(level);
4283             app.trimMemoryLevel = level;
4284             return true;
4285         }
4286     }
4287
4288     private void dispatchProcessesChanged() {
4289         int N;
4290         synchronized (this) {
4291             N = mPendingProcessChanges.size();
4292             if (mActiveProcessChanges.length < N) {
4293                 mActiveProcessChanges = new ProcessChangeItem[N];
4294             }
4295             mPendingProcessChanges.toArray(mActiveProcessChanges);
4296             mPendingProcessChanges.clear();
4297             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4298                     "*** Delivering " + N + " process changes");
4299         }
4300
4301         int i = mProcessObservers.beginBroadcast();
4302         while (i > 0) {
4303             i--;
4304             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4305             if (observer != null) {
4306                 try {
4307                     for (int j=0; j<N; j++) {
4308                         ProcessChangeItem item = mActiveProcessChanges[j];
4309                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4310                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4311                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4312                                     + item.uid + ": " + item.foregroundActivities);
4313                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4314                                     item.foregroundActivities);
4315                         }
4316                     }
4317                 } catch (RemoteException e) {
4318                 }
4319             }
4320         }
4321         mProcessObservers.finishBroadcast();
4322
4323         synchronized (this) {
4324             for (int j=0; j<N; j++) {
4325                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4326             }
4327         }
4328     }
4329
4330     private void dispatchProcessDied(int pid, int uid) {
4331         int i = mProcessObservers.beginBroadcast();
4332         while (i > 0) {
4333             i--;
4334             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4335             if (observer != null) {
4336                 try {
4337                     observer.onProcessDied(pid, uid);
4338                 } catch (RemoteException e) {
4339                 }
4340             }
4341         }
4342         mProcessObservers.finishBroadcast();
4343     }
4344
4345     @VisibleForTesting
4346     void dispatchUidsChanged() {
4347         int N;
4348         synchronized (this) {
4349             N = mPendingUidChanges.size();
4350             if (mActiveUidChanges.length < N) {
4351                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4352             }
4353             for (int i=0; i<N; i++) {
4354                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4355                 mActiveUidChanges[i] = change;
4356                 if (change.uidRecord != null) {
4357                     change.uidRecord.pendingChange = null;
4358                     change.uidRecord = null;
4359                 }
4360             }
4361             mPendingUidChanges.clear();
4362             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4363                     "*** Delivering " + N + " uid changes");
4364         }
4365
4366         int i = mUidObservers.beginBroadcast();
4367         while (i > 0) {
4368             i--;
4369             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4370                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4371         }
4372         mUidObservers.finishBroadcast();
4373
4374         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4375             for (int j = 0; j < N; ++j) {
4376                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4377                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4378                     mValidateUids.remove(item.uid);
4379                 } else {
4380                     UidRecord validateUid = mValidateUids.get(item.uid);
4381                     if (validateUid == null) {
4382                         validateUid = new UidRecord(item.uid);
4383                         mValidateUids.put(item.uid, validateUid);
4384                     }
4385                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4386                         validateUid.idle = true;
4387                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4388                         validateUid.idle = false;
4389                     }
4390                     validateUid.curProcState = validateUid.setProcState = item.processState;
4391                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4392                 }
4393             }
4394         }
4395
4396         synchronized (this) {
4397             for (int j = 0; j < N; j++) {
4398                 mAvailUidChanges.add(mActiveUidChanges[j]);
4399             }
4400         }
4401     }
4402
4403     private void dispatchUidsChangedForObserver(IUidObserver observer,
4404             UidObserverRegistration reg, int changesSize) {
4405         if (observer == null) {
4406             return;
4407         }
4408         try {
4409             for (int j = 0; j < changesSize; j++) {
4410                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4411                 final int change = item.change;
4412                 if (change == UidRecord.CHANGE_PROCSTATE &&
4413                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4414                     // No-op common case: no significant change, the observer is not
4415                     // interested in all proc state changes.
4416                     continue;
4417                 }
4418                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4419                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4420                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4421                                 "UID idle uid=" + item.uid);
4422                         observer.onUidIdle(item.uid, item.ephemeral);
4423                     }
4424                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4425                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4426                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4427                                 "UID active uid=" + item.uid);
4428                         observer.onUidActive(item.uid);
4429                     }
4430                 }
4431                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4432                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
4433                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4434                                 "UID cached uid=" + item.uid);
4435                         observer.onUidCachedChanged(item.uid, true);
4436                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4437                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4438                                 "UID active uid=" + item.uid);
4439                         observer.onUidCachedChanged(item.uid, false);
4440                     }
4441                 }
4442                 if ((change & UidRecord.CHANGE_GONE) != 0) {
4443                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4444                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4445                                 "UID gone uid=" + item.uid);
4446                         observer.onUidGone(item.uid, item.ephemeral);
4447                     }
4448                     if (reg.lastProcStates != null) {
4449                         reg.lastProcStates.delete(item.uid);
4450                     }
4451                 } else {
4452                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4453                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4454                                 "UID CHANGED uid=" + item.uid
4455                                         + ": " + item.processState);
4456                         boolean doReport = true;
4457                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4458                             final int lastState = reg.lastProcStates.get(item.uid,
4459                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4460                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4461                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4462                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4463                                 doReport = lastAboveCut != newAboveCut;
4464                             } else {
4465                                 doReport = item.processState
4466                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4467                             }
4468                         }
4469                         if (doReport) {
4470                             if (reg.lastProcStates != null) {
4471                                 reg.lastProcStates.put(item.uid, item.processState);
4472                             }
4473                             observer.onUidStateChanged(item.uid, item.processState,
4474                                     item.procStateSeq);
4475                         }
4476                     }
4477                 }
4478             }
4479         } catch (RemoteException e) {
4480         }
4481     }
4482
4483     void dispatchOomAdjObserver(String msg) {
4484         OomAdjObserver observer;
4485         synchronized (this) {
4486             observer = mCurOomAdjObserver;
4487         }
4488
4489         if (observer != null) {
4490             observer.onOomAdjMessage(msg);
4491         }
4492     }
4493
4494     void setOomAdjObserver(int uid, OomAdjObserver observer) {
4495         synchronized (this) {
4496             mCurOomAdjUid = uid;
4497             mCurOomAdjObserver = observer;
4498         }
4499     }
4500
4501     void clearOomAdjObserver() {
4502         synchronized (this) {
4503             mCurOomAdjUid = -1;
4504             mCurOomAdjObserver = null;
4505         }
4506     }
4507
4508     void reportOomAdjMessageLocked(String tag, String msg) {
4509         Slog.d(tag, msg);
4510         if (mCurOomAdjObserver != null) {
4511             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4512         }
4513     }
4514
4515     @Override
4516     public final int startActivity(IApplicationThread caller, String callingPackage,
4517             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4518             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4519         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4520                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4521                 UserHandle.getCallingUserId());
4522     }
4523
4524     @Override
4525     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4526             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4527             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4528         enforceNotIsolatedCaller("startActivity");
4529         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4530                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4531         // TODO: Switch to user app stacks here.
4532         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4533                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4534                 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4535     }
4536
4537     @Override
4538     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4539             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4540             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4541             int userId) {
4542
4543         // This is very dangerous -- it allows you to perform a start activity (including
4544         // permission grants) as any app that may launch one of your own activities.  So
4545         // we will only allow this to be done from activities that are part of the core framework,
4546         // and then only when they are running as the system.
4547         final ActivityRecord sourceRecord;
4548         final int targetUid;
4549         final String targetPackage;
4550         synchronized (this) {
4551             if (resultTo == null) {
4552                 throw new SecurityException("Must be called from an activity");
4553             }
4554             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4555             if (sourceRecord == null) {
4556                 throw new SecurityException("Called with bad activity token: " + resultTo);
4557             }
4558             if (!sourceRecord.info.packageName.equals("android")) {
4559                 throw new SecurityException(
4560                         "Must be called from an activity that is declared in the android package");
4561             }
4562             if (sourceRecord.app == null) {
4563                 throw new SecurityException("Called without a process attached to activity");
4564             }
4565             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4566                 // This is still okay, as long as this activity is running under the
4567                 // uid of the original calling activity.
4568                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4569                     throw new SecurityException(
4570                             "Calling activity in uid " + sourceRecord.app.uid
4571                                     + " must be system uid or original calling uid "
4572                                     + sourceRecord.launchedFromUid);
4573                 }
4574             }
4575             if (ignoreTargetSecurity) {
4576                 if (intent.getComponent() == null) {
4577                     throw new SecurityException(
4578                             "Component must be specified with ignoreTargetSecurity");
4579                 }
4580                 if (intent.getSelector() != null) {
4581                     throw new SecurityException(
4582                             "Selector not allowed with ignoreTargetSecurity");
4583                 }
4584             }
4585             targetUid = sourceRecord.launchedFromUid;
4586             targetPackage = sourceRecord.launchedFromPackage;
4587         }
4588
4589         if (userId == UserHandle.USER_NULL) {
4590             userId = UserHandle.getUserId(sourceRecord.app.uid);
4591         }
4592
4593         // TODO: Switch to user app stacks here.
4594         try {
4595             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4596                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4597                     null, null, bOptions, ignoreTargetSecurity, userId, null,
4598                     "startActivityAsCaller");
4599             return ret;
4600         } catch (SecurityException e) {
4601             // XXX need to figure out how to propagate to original app.
4602             // A SecurityException here is generally actually a fault of the original
4603             // calling activity (such as a fairly granting permissions), so propagate it
4604             // back to them.
4605             /*
4606             StringBuilder msg = new StringBuilder();
4607             msg.append("While launching");
4608             msg.append(intent.toString());
4609             msg.append(": ");
4610             msg.append(e.getMessage());
4611             */
4612             throw e;
4613         }
4614     }
4615
4616     @Override
4617     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4618             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4619             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4620         enforceNotIsolatedCaller("startActivityAndWait");
4621         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4622                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4623         WaitResult res = new WaitResult();
4624         // TODO: Switch to user app stacks here.
4625         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4626                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4627                 bOptions, false, userId, null, "startActivityAndWait");
4628         return res;
4629     }
4630
4631     @Override
4632     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4633             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4634             int startFlags, Configuration config, Bundle bOptions, int userId) {
4635         enforceNotIsolatedCaller("startActivityWithConfig");
4636         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4637                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4638         // TODO: Switch to user app stacks here.
4639         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4640                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4641                 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4642         return ret;
4643     }
4644
4645     @Override
4646     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4647             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4648             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4649             throws TransactionTooLargeException {
4650         enforceNotIsolatedCaller("startActivityIntentSender");
4651         // Refuse possible leaked file descriptors
4652         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4653             throw new IllegalArgumentException("File descriptors passed in Intent");
4654         }
4655
4656         if (!(target instanceof PendingIntentRecord)) {
4657             throw new IllegalArgumentException("Bad PendingIntent object");
4658         }
4659
4660         PendingIntentRecord pir = (PendingIntentRecord)target;
4661
4662         synchronized (this) {
4663             // If this is coming from the currently resumed activity, it is
4664             // effectively saying that app switches are allowed at this point.
4665             final ActivityStack stack = getFocusedStack();
4666             if (stack.mResumedActivity != null &&
4667                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4668                 mAppSwitchesAllowedTime = 0;
4669             }
4670         }
4671         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4672                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4673         return ret;
4674     }
4675
4676     @Override
4677     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4678             Intent intent, String resolvedType, IVoiceInteractionSession session,
4679             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4680             Bundle bOptions, int userId) {
4681         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4682                 != PackageManager.PERMISSION_GRANTED) {
4683             String msg = "Permission Denial: startVoiceActivity() from pid="
4684                     + Binder.getCallingPid()
4685                     + ", uid=" + Binder.getCallingUid()
4686                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4687             Slog.w(TAG, msg);
4688             throw new SecurityException(msg);
4689         }
4690         if (session == null || interactor == null) {
4691             throw new NullPointerException("null session or interactor");
4692         }
4693         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4694                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4695         // TODO: Switch to user app stacks here.
4696         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4697                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4698                 null, bOptions, false, userId, null, "startVoiceActivity");
4699     }
4700
4701     @Override
4702     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4703             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4704         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4705                 != PackageManager.PERMISSION_GRANTED) {
4706             final String msg = "Permission Denial: startAssistantActivity() from pid="
4707                     + Binder.getCallingPid()
4708                     + ", uid=" + Binder.getCallingUid()
4709                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4710             Slog.w(TAG, msg);
4711             throw new SecurityException(msg);
4712         }
4713         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4714                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4715         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4716                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4717                 userId, null, "startAssistantActivity");
4718     }
4719
4720     @Override
4721     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4722             throws RemoteException {
4723         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4724         synchronized (this) {
4725             ActivityRecord activity = getFocusedStack().topActivity();
4726             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4727                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4728             }
4729             if (mRunningVoice != null || activity.getTask().voiceSession != null
4730                     || activity.voiceSession != null) {
4731                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4732                 return;
4733             }
4734             if (activity.pendingVoiceInteractionStart) {
4735                 Slog.w(TAG, "Pending start of voice interaction already.");
4736                 return;
4737             }
4738             activity.pendingVoiceInteractionStart = true;
4739         }
4740         LocalServices.getService(VoiceInteractionManagerInternal.class)
4741                 .startLocalVoiceInteraction(callingActivity, options);
4742     }
4743
4744     @Override
4745     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4746         LocalServices.getService(VoiceInteractionManagerInternal.class)
4747                 .stopLocalVoiceInteraction(callingActivity);
4748     }
4749
4750     @Override
4751     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4752         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4753                 .supportsLocalVoiceInteraction();
4754     }
4755
4756     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4757             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4758         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4759         if (activityToCallback == null) return;
4760         activityToCallback.setVoiceSessionLocked(voiceSession);
4761
4762         // Inform the activity
4763         try {
4764             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4765                     voiceInteractor);
4766             long token = Binder.clearCallingIdentity();
4767             try {
4768                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4769             } finally {
4770                 Binder.restoreCallingIdentity(token);
4771             }
4772             // TODO: VI Should we cache the activity so that it's easier to find later
4773             // rather than scan through all the stacks and activities?
4774         } catch (RemoteException re) {
4775             activityToCallback.clearVoiceSessionLocked();
4776             // TODO: VI Should this terminate the voice session?
4777         }
4778     }
4779
4780     @Override
4781     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4782         synchronized (this) {
4783             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4784                 if (keepAwake) {
4785                     mVoiceWakeLock.acquire();
4786                 } else {
4787                     mVoiceWakeLock.release();
4788                 }
4789             }
4790         }
4791     }
4792
4793     @Override
4794     public boolean startNextMatchingActivity(IBinder callingActivity,
4795             Intent intent, Bundle bOptions) {
4796         // Refuse possible leaked file descriptors
4797         if (intent != null && intent.hasFileDescriptors() == true) {
4798             throw new IllegalArgumentException("File descriptors passed in Intent");
4799         }
4800         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4801
4802         synchronized (this) {
4803             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4804             if (r == null) {
4805                 ActivityOptions.abort(options);
4806                 return false;
4807             }
4808             if (r.app == null || r.app.thread == null) {
4809                 // The caller is not running...  d'oh!
4810                 ActivityOptions.abort(options);
4811                 return false;
4812             }
4813             intent = new Intent(intent);
4814             // The caller is not allowed to change the data.
4815             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4816             // And we are resetting to find the next component...
4817             intent.setComponent(null);
4818
4819             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4820
4821             ActivityInfo aInfo = null;
4822             try {
4823                 List<ResolveInfo> resolves =
4824                     AppGlobals.getPackageManager().queryIntentActivities(
4825                             intent, r.resolvedType,
4826                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4827                             UserHandle.getCallingUserId()).getList();
4828
4829                 // Look for the original activity in the list...
4830                 final int N = resolves != null ? resolves.size() : 0;
4831                 for (int i=0; i<N; i++) {
4832                     ResolveInfo rInfo = resolves.get(i);
4833                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4834                             && rInfo.activityInfo.name.equals(r.info.name)) {
4835                         // We found the current one...  the next matching is
4836                         // after it.
4837                         i++;
4838                         if (i<N) {
4839                             aInfo = resolves.get(i).activityInfo;
4840                         }
4841                         if (debug) {
4842                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4843                                     + "/" + r.info.name);
4844                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4845                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4846                         }
4847                         break;
4848                     }
4849                 }
4850             } catch (RemoteException e) {
4851             }
4852
4853             if (aInfo == null) {
4854                 // Nobody who is next!
4855                 ActivityOptions.abort(options);
4856                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4857                 return false;
4858             }
4859
4860             intent.setComponent(new ComponentName(
4861                     aInfo.applicationInfo.packageName, aInfo.name));
4862             intent.setFlags(intent.getFlags()&~(
4863                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4864                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4865                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4866                     Intent.FLAG_ACTIVITY_NEW_TASK));
4867
4868             // Okay now we need to start the new activity, replacing the
4869             // currently running activity.  This is a little tricky because
4870             // we want to start the new one as if the current one is finished,
4871             // but not finish the current one first so that there is no flicker.
4872             // And thus...
4873             final boolean wasFinishing = r.finishing;
4874             r.finishing = true;
4875
4876             // Propagate reply information over to the new activity.
4877             final ActivityRecord resultTo = r.resultTo;
4878             final String resultWho = r.resultWho;
4879             final int requestCode = r.requestCode;
4880             r.resultTo = null;
4881             if (resultTo != null) {
4882                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4883             }
4884
4885             final long origId = Binder.clearCallingIdentity();
4886             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4887                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4888                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4889                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4890                     false, false, null, null, "startNextMatchingActivity");
4891             Binder.restoreCallingIdentity(origId);
4892
4893             r.finishing = wasFinishing;
4894             if (res != ActivityManager.START_SUCCESS) {
4895                 return false;
4896             }
4897             return true;
4898         }
4899     }
4900
4901     @Override
4902     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4903         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4904             String msg = "Permission Denial: startActivityFromRecents called without " +
4905                     START_TASKS_FROM_RECENTS;
4906             Slog.w(TAG, msg);
4907             throw new SecurityException(msg);
4908         }
4909         final long origId = Binder.clearCallingIdentity();
4910         try {
4911             synchronized (this) {
4912                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4913             }
4914         } finally {
4915             Binder.restoreCallingIdentity(origId);
4916         }
4917     }
4918
4919     final int startActivityInPackage(int uid, String callingPackage,
4920             Intent intent, String resolvedType, IBinder resultTo,
4921             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4922             TaskRecord inTask, String reason) {
4923
4924         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4925                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4926
4927         // TODO: Switch to user app stacks here.
4928         return mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4929                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4930                 null, null, null, bOptions, false, userId, inTask, reason);
4931     }
4932
4933     @Override
4934     public final int startActivities(IApplicationThread caller, String callingPackage,
4935             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4936             int userId) {
4937         final String reason = "startActivities";
4938         enforceNotIsolatedCaller(reason);
4939         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4940                 userId, false, ALLOW_FULL_ONLY, reason, null);
4941         // TODO: Switch to user app stacks here.
4942         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4943                 resolvedTypes, resultTo, bOptions, userId, reason);
4944         return ret;
4945     }
4946
4947     final int startActivitiesInPackage(int uid, String callingPackage,
4948             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4949             Bundle bOptions, int userId) {
4950
4951         final String reason = "startActivityInPackage";
4952         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4953                 userId, false, ALLOW_FULL_ONLY, reason, null);
4954         // TODO: Switch to user app stacks here.
4955         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4956                 resultTo, bOptions, userId, reason);
4957         return ret;
4958     }
4959
4960     @Override
4961     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4962         synchronized (this) {
4963             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4964             if (r == null) {
4965                 return;
4966             }
4967             r.reportFullyDrawnLocked(restoredFromBundle);
4968         }
4969     }
4970
4971     @Override
4972     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4973         synchronized (this) {
4974             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4975             if (r == null) {
4976                 return;
4977             }
4978             final long origId = Binder.clearCallingIdentity();
4979             try {
4980                 r.setRequestedOrientation(requestedOrientation);
4981             } finally {
4982                 Binder.restoreCallingIdentity(origId);
4983             }
4984         }
4985     }
4986
4987     @Override
4988     public int getRequestedOrientation(IBinder token) {
4989         synchronized (this) {
4990             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4991             if (r == null) {
4992                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4993             }
4994             return r.getRequestedOrientation();
4995         }
4996     }
4997
4998     @Override
4999     public final void requestActivityRelaunch(IBinder token) {
5000         synchronized(this) {
5001             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5002             if (r == null) {
5003                 return;
5004             }
5005             final long origId = Binder.clearCallingIdentity();
5006             try {
5007                 r.forceNewConfig = true;
5008                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5009                         true /* preserveWindow */);
5010             } finally {
5011                 Binder.restoreCallingIdentity(origId);
5012             }
5013         }
5014     }
5015
5016     /**
5017      * This is the internal entry point for handling Activity.finish().
5018      *
5019      * @param token The Binder token referencing the Activity we want to finish.
5020      * @param resultCode Result code, if any, from this Activity.
5021      * @param resultData Result data (Intent), if any, from this Activity.
5022      * @param finishTask Whether to finish the task associated with this Activity.
5023      *
5024      * @return Returns true if the activity successfully finished, or false if it is still running.
5025      */
5026     @Override
5027     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5028             int finishTask) {
5029         // Refuse possible leaked file descriptors
5030         if (resultData != null && resultData.hasFileDescriptors() == true) {
5031             throw new IllegalArgumentException("File descriptors passed in Intent");
5032         }
5033
5034         synchronized(this) {
5035             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5036             if (r == null) {
5037                 return true;
5038             }
5039             // Keep track of the root activity of the task before we finish it
5040             TaskRecord tr = r.getTask();
5041             ActivityRecord rootR = tr.getRootActivity();
5042             if (rootR == null) {
5043                 Slog.w(TAG, "Finishing task with all activities already finished");
5044             }
5045             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5046             // finish.
5047             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5048                     mStackSupervisor.isLastLockedTask(tr)) {
5049                 Slog.i(TAG, "Not finishing task in lock task mode");
5050                 mStackSupervisor.showLockTaskToast();
5051                 return false;
5052             }
5053             if (mController != null) {
5054                 // Find the first activity that is not finishing.
5055                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5056                 if (next != null) {
5057                     // ask watcher if this is allowed
5058                     boolean resumeOK = true;
5059                     try {
5060                         resumeOK = mController.activityResuming(next.packageName);
5061                     } catch (RemoteException e) {
5062                         mController = null;
5063                         Watchdog.getInstance().setActivityController(null);
5064                     }
5065
5066                     if (!resumeOK) {
5067                         Slog.i(TAG, "Not finishing activity because controller resumed");
5068                         return false;
5069                     }
5070                 }
5071             }
5072             final long origId = Binder.clearCallingIdentity();
5073             try {
5074                 boolean res;
5075                 final boolean finishWithRootActivity =
5076                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5077                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5078                         || (finishWithRootActivity && r == rootR)) {
5079                     // If requested, remove the task that is associated to this activity only if it
5080                     // was the root activity in the task. The result code and data is ignored
5081                     // because we don't support returning them across task boundaries. Also, to
5082                     // keep backwards compatibility we remove the task from recents when finishing
5083                     // task with root activity.
5084                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5085                     if (!res) {
5086                         Slog.i(TAG, "Removing task failed to finish activity");
5087                     }
5088                 } else {
5089                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5090                             resultData, "app-request", true);
5091                     if (!res) {
5092                         Slog.i(TAG, "Failed to finish by app-request");
5093                     }
5094                 }
5095                 return res;
5096             } finally {
5097                 Binder.restoreCallingIdentity(origId);
5098             }
5099         }
5100     }
5101
5102     @Override
5103     public final void finishHeavyWeightApp() {
5104         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5105                 != PackageManager.PERMISSION_GRANTED) {
5106             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5107                     + Binder.getCallingPid()
5108                     + ", uid=" + Binder.getCallingUid()
5109                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5110             Slog.w(TAG, msg);
5111             throw new SecurityException(msg);
5112         }
5113
5114         synchronized(this) {
5115             if (mHeavyWeightProcess == null) {
5116                 return;
5117             }
5118
5119             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5120             for (int i = 0; i < activities.size(); i++) {
5121                 ActivityRecord r = activities.get(i);
5122                 if (!r.finishing && r.isInStackLocked()) {
5123                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5124                             null, "finish-heavy", true);
5125                 }
5126             }
5127
5128             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5129                     mHeavyWeightProcess.userId, 0));
5130             mHeavyWeightProcess = null;
5131         }
5132     }
5133
5134     @Override
5135     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5136             String message) {
5137         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5138                 != PackageManager.PERMISSION_GRANTED) {
5139             String msg = "Permission Denial: crashApplication() from pid="
5140                     + Binder.getCallingPid()
5141                     + ", uid=" + Binder.getCallingUid()
5142                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5143             Slog.w(TAG, msg);
5144             throw new SecurityException(msg);
5145         }
5146
5147         synchronized(this) {
5148             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5149         }
5150     }
5151
5152     @Override
5153     public final void finishSubActivity(IBinder token, String resultWho,
5154             int requestCode) {
5155         synchronized(this) {
5156             final long origId = Binder.clearCallingIdentity();
5157             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5158             if (r != null) {
5159                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5160             }
5161             Binder.restoreCallingIdentity(origId);
5162         }
5163     }
5164
5165     @Override
5166     public boolean finishActivityAffinity(IBinder token) {
5167         synchronized(this) {
5168             final long origId = Binder.clearCallingIdentity();
5169             try {
5170                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5171                 if (r == null) {
5172                     return false;
5173                 }
5174
5175                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5176                 // can finish.
5177                 final TaskRecord task = r.getTask();
5178                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5179                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5180                     mStackSupervisor.showLockTaskToast();
5181                     return false;
5182                 }
5183                 return task.getStack().finishActivityAffinityLocked(r);
5184             } finally {
5185                 Binder.restoreCallingIdentity(origId);
5186             }
5187         }
5188     }
5189
5190     @Override
5191     public void finishVoiceTask(IVoiceInteractionSession session) {
5192         synchronized (this) {
5193             final long origId = Binder.clearCallingIdentity();
5194             try {
5195                 // TODO: VI Consider treating local voice interactions and voice tasks
5196                 // differently here
5197                 mStackSupervisor.finishVoiceTask(session);
5198             } finally {
5199                 Binder.restoreCallingIdentity(origId);
5200             }
5201         }
5202
5203     }
5204
5205     @Override
5206     public boolean releaseActivityInstance(IBinder token) {
5207         synchronized(this) {
5208             final long origId = Binder.clearCallingIdentity();
5209             try {
5210                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5211                 if (r == null) {
5212                     return false;
5213                 }
5214                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5215             } finally {
5216                 Binder.restoreCallingIdentity(origId);
5217             }
5218         }
5219     }
5220
5221     @Override
5222     public void releaseSomeActivities(IApplicationThread appInt) {
5223         synchronized(this) {
5224             final long origId = Binder.clearCallingIdentity();
5225             try {
5226                 ProcessRecord app = getRecordForAppLocked(appInt);
5227                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5228             } finally {
5229                 Binder.restoreCallingIdentity(origId);
5230             }
5231         }
5232     }
5233
5234     @Override
5235     public boolean willActivityBeVisible(IBinder token) {
5236         synchronized(this) {
5237             ActivityStack stack = ActivityRecord.getStackLocked(token);
5238             if (stack != null) {
5239                 return stack.willActivityBeVisibleLocked(token);
5240             }
5241             return false;
5242         }
5243     }
5244
5245     @Override
5246     public void overridePendingTransition(IBinder token, String packageName,
5247             int enterAnim, int exitAnim) {
5248         synchronized(this) {
5249             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5250             if (self == null) {
5251                 return;
5252             }
5253
5254             final long origId = Binder.clearCallingIdentity();
5255
5256             if (self.state == ActivityState.RESUMED
5257                     || self.state == ActivityState.PAUSING) {
5258                 mWindowManager.overridePendingAppTransition(packageName,
5259                         enterAnim, exitAnim, null);
5260             }
5261
5262             Binder.restoreCallingIdentity(origId);
5263         }
5264     }
5265
5266     /**
5267      * Main function for removing an existing process from the activity manager
5268      * as a result of that process going away.  Clears out all connections
5269      * to the process.
5270      */
5271     private final void handleAppDiedLocked(ProcessRecord app,
5272             boolean restarting, boolean allowRestart) {
5273         int pid = app.pid;
5274         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5275                 false /*replacingPid*/);
5276         if (!kept && !restarting) {
5277             removeLruProcessLocked(app);
5278             if (pid > 0) {
5279                 ProcessList.remove(pid);
5280             }
5281         }
5282
5283         if (mProfileProc == app) {
5284             clearProfilerLocked();
5285         }
5286
5287         // Remove this application's activities from active lists.
5288         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5289
5290         app.activities.clear();
5291
5292         if (app.instr != null) {
5293             Slog.w(TAG, "Crash of app " + app.processName
5294                   + " running instrumentation " + app.instr.mClass);
5295             Bundle info = new Bundle();
5296             info.putString("shortMsg", "Process crashed.");
5297             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5298         }
5299
5300         mWindowManager.deferSurfaceLayout();
5301         try {
5302             if (!restarting && hasVisibleActivities
5303                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5304                 // If there was nothing to resume, and we are not already restarting this process, but
5305                 // there is a visible activity that is hosted by the process...  then make sure all
5306                 // visible activities are running, taking care of restarting this process.
5307                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5308             }
5309         } finally {
5310             mWindowManager.continueSurfaceLayout();
5311         }
5312     }
5313
5314     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5315         final IBinder threadBinder = thread.asBinder();
5316         // Find the application record.
5317         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5318             final ProcessRecord rec = mLruProcesses.get(i);
5319             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5320                 return i;
5321             }
5322         }
5323         return -1;
5324     }
5325
5326     final ProcessRecord getRecordForAppLocked(
5327             IApplicationThread thread) {
5328         if (thread == null) {
5329             return null;
5330         }
5331
5332         int appIndex = getLRURecordIndexForAppLocked(thread);
5333         if (appIndex >= 0) {
5334             return mLruProcesses.get(appIndex);
5335         }
5336
5337         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5338         // double-check that.
5339         final IBinder threadBinder = thread.asBinder();
5340         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5341         for (int i = pmap.size()-1; i >= 0; i--) {
5342             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5343             for (int j = procs.size()-1; j >= 0; j--) {
5344                 final ProcessRecord proc = procs.valueAt(j);
5345                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5346                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5347                             + proc);
5348                     return proc;
5349                 }
5350             }
5351         }
5352
5353         return null;
5354     }
5355
5356     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5357         // If there are no longer any background processes running,
5358         // and the app that died was not running instrumentation,
5359         // then tell everyone we are now low on memory.
5360         boolean haveBg = false;
5361         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5362             ProcessRecord rec = mLruProcesses.get(i);
5363             if (rec.thread != null
5364                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5365                 haveBg = true;
5366                 break;
5367             }
5368         }
5369
5370         if (!haveBg) {
5371             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5372             if (doReport) {
5373                 long now = SystemClock.uptimeMillis();
5374                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5375                     doReport = false;
5376                 } else {
5377                     mLastMemUsageReportTime = now;
5378                 }
5379             }
5380             final ArrayList<ProcessMemInfo> memInfos
5381                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5382             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5383             long now = SystemClock.uptimeMillis();
5384             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5385                 ProcessRecord rec = mLruProcesses.get(i);
5386                 if (rec == dyingProc || rec.thread == null) {
5387                     continue;
5388                 }
5389                 if (doReport) {
5390                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5391                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5392                 }
5393                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5394                     // The low memory report is overriding any current
5395                     // state for a GC request.  Make sure to do
5396                     // heavy/important/visible/foreground processes first.
5397                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5398                         rec.lastRequestedGc = 0;
5399                     } else {
5400                         rec.lastRequestedGc = rec.lastLowMemory;
5401                     }
5402                     rec.reportLowMemory = true;
5403                     rec.lastLowMemory = now;
5404                     mProcessesToGc.remove(rec);
5405                     addProcessToGcListLocked(rec);
5406                 }
5407             }
5408             if (doReport) {
5409                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5410                 mHandler.sendMessage(msg);
5411             }
5412             scheduleAppGcsLocked();
5413         }
5414     }
5415
5416     final void appDiedLocked(ProcessRecord app) {
5417        appDiedLocked(app, app.pid, app.thread, false);
5418     }
5419
5420     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5421             boolean fromBinderDied) {
5422         // First check if this ProcessRecord is actually active for the pid.
5423         synchronized (mPidsSelfLocked) {
5424             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5425             if (curProc != app) {
5426                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5427                 return;
5428             }
5429         }
5430
5431         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5432         synchronized (stats) {
5433             stats.noteProcessDiedLocked(app.info.uid, pid);
5434         }
5435
5436         if (!app.killed) {
5437             if (!fromBinderDied) {
5438                 killProcessQuiet(pid);
5439             }
5440             killProcessGroup(app.uid, pid);
5441             app.killed = true;
5442         }
5443
5444         // Clean up already done if the process has been re-started.
5445         if (app.pid == pid && app.thread != null &&
5446                 app.thread.asBinder() == thread.asBinder()) {
5447             boolean doLowMem = app.instr == null;
5448             boolean doOomAdj = doLowMem;
5449             if (!app.killedByAm) {
5450                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5451                         + ProcessList.makeOomAdjString(app.setAdj)
5452                         + ProcessList.makeProcStateString(app.setProcState));
5453                 mAllowLowerMemLevel = true;
5454             } else {
5455                 // Note that we always want to do oom adj to update our state with the
5456                 // new number of procs.
5457                 mAllowLowerMemLevel = false;
5458                 doLowMem = false;
5459             }
5460             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5461                     app.setAdj, app.setProcState);
5462             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5463                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5464             handleAppDiedLocked(app, false, true);
5465
5466             if (doOomAdj) {
5467                 updateOomAdjLocked();
5468             }
5469             if (doLowMem) {
5470                 doLowMemReportIfNeededLocked(app);
5471             }
5472         } else if (app.pid != pid) {
5473             // A new process has already been started.
5474             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5475                     + ") has died and restarted (pid " + app.pid + ").");
5476             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5477         } else if (DEBUG_PROCESSES) {
5478             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5479                     + thread.asBinder());
5480         }
5481     }
5482
5483     /**
5484      * If a stack trace dump file is configured, dump process stack traces.
5485      * @param clearTraces causes the dump file to be erased prior to the new
5486      *    traces being written, if true; when false, the new traces will be
5487      *    appended to any existing file content.
5488      * @param firstPids of dalvik VM processes to dump stack traces for first
5489      * @param lastPids of dalvik VM processes to dump stack traces for last
5490      * @param nativePids optional list of native pids to dump stack crawls
5491      */
5492     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5493             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5494             ArrayList<Integer> nativePids) {
5495         ArrayList<Integer> extraPids = null;
5496
5497         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5498         // of the top users at the time of the request.
5499         if (processCpuTracker != null) {
5500             processCpuTracker.init();
5501             try {
5502                 Thread.sleep(200);
5503             } catch (InterruptedException ignored) {
5504             }
5505
5506             processCpuTracker.update();
5507
5508             // We'll take the stack crawls of just the top apps using CPU.
5509             final int N = processCpuTracker.countWorkingStats();
5510             extraPids = new ArrayList<>();
5511             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5512                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5513                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5514                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5515
5516                     extraPids.add(stats.pid);
5517                 } else if (DEBUG_ANR) {
5518                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5519                             + stats.pid);
5520                 }
5521             }
5522         }
5523
5524         boolean useTombstonedForJavaTraces = false;
5525         File tracesFile;
5526
5527         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5528         if (tracesDirProp.isEmpty()) {
5529             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5530             // dumping scheme. All traces are written to a global trace file (usually
5531             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5532             // the file if requested.
5533             //
5534             // This mode of operation will be removed in the near future.
5535
5536
5537             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5538             if (globalTracesPath.isEmpty()) {
5539                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5540                 return null;
5541             }
5542
5543             tracesFile = new File(globalTracesPath);
5544             try {
5545                 if (clearTraces && tracesFile.exists()) {
5546                     tracesFile.delete();
5547                 }
5548
5549                 tracesFile.createNewFile();
5550                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5551             } catch (IOException e) {
5552                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5553                 return null;
5554             }
5555         } else {
5556             File tracesDir = new File(tracesDirProp);
5557             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5558             // Each set of ANR traces is written to a separate file and dumpstate will process
5559             // all such files and add them to a captured bug report if they're recent enough.
5560             maybePruneOldTraces(tracesDir);
5561
5562             // NOTE: We should consider creating the file in native code atomically once we've
5563             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5564             // can be removed.
5565             tracesFile = createAnrDumpFile(tracesDir);
5566             if (tracesFile == null) {
5567                 return null;
5568             }
5569
5570             useTombstonedForJavaTraces = true;
5571         }
5572
5573         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5574                 useTombstonedForJavaTraces);
5575         return tracesFile;
5576     }
5577
5578     @GuardedBy("ActivityManagerService.class")
5579     private static SimpleDateFormat sAnrFileDateFormat;
5580
5581     private static synchronized File createAnrDumpFile(File tracesDir) {
5582         if (sAnrFileDateFormat == null) {
5583             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5584         }
5585
5586         final String formattedDate = sAnrFileDateFormat.format(new Date());
5587         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5588
5589         try {
5590             if (anrFile.createNewFile()) {
5591                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5592                 return anrFile;
5593             } else {
5594                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5595             }
5596         } catch (IOException ioe) {
5597             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5598         }
5599
5600         return null;
5601     }
5602
5603     /**
5604      * Prune all trace files that are more than a day old.
5605      *
5606      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5607      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5608      * since it's the system_server that creates trace files for most ANRs.
5609      */
5610     private static void maybePruneOldTraces(File tracesDir) {
5611         final long now = System.currentTimeMillis();
5612         final File[] traceFiles = tracesDir.listFiles();
5613
5614         if (traceFiles != null) {
5615             for (File file : traceFiles) {
5616                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5617                     if (!file.delete()) {
5618                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
5619                     }
5620                 }
5621             }
5622         }
5623     }
5624
5625     /**
5626      * Legacy code, do not use. Existing users will be deleted.
5627      *
5628      * @deprecated
5629      */
5630     @Deprecated
5631     public static class DumpStackFileObserver extends FileObserver {
5632         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5633         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5634
5635         private final String mTracesPath;
5636         private boolean mClosed;
5637
5638         public DumpStackFileObserver(String tracesPath) {
5639             super(tracesPath, FileObserver.CLOSE_WRITE);
5640             mTracesPath = tracesPath;
5641         }
5642
5643         @Override
5644         public synchronized void onEvent(int event, String path) {
5645             mClosed = true;
5646             notify();
5647         }
5648
5649         public long dumpWithTimeout(int pid, long timeout) {
5650             sendSignal(pid, SIGNAL_QUIT);
5651             final long start = SystemClock.elapsedRealtime();
5652
5653             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5654             synchronized (this) {
5655                 try {
5656                     wait(waitTime); // Wait for traces file to be closed.
5657                 } catch (InterruptedException e) {
5658                     Slog.wtf(TAG, e);
5659                 }
5660             }
5661
5662             // This avoids a corner case of passing a negative time to the native
5663             // trace in case we've already hit the overall timeout.
5664             final long timeWaited = SystemClock.elapsedRealtime() - start;
5665             if (timeWaited >= timeout) {
5666                 return timeWaited;
5667             }
5668
5669             if (!mClosed) {
5670                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5671                        ". Attempting native stack collection.");
5672
5673                 final long nativeDumpTimeoutMs = Math.min(
5674                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5675
5676                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5677                         (int) (nativeDumpTimeoutMs / 1000));
5678             }
5679
5680             final long end = SystemClock.elapsedRealtime();
5681             mClosed = false;
5682
5683             return (end - start);
5684         }
5685     }
5686
5687     /**
5688      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5689      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5690      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5691      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5692      * capturing traces.
5693      */
5694     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5695         final long timeStart = SystemClock.elapsedRealtime();
5696         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5697             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5698                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5699         }
5700
5701         return SystemClock.elapsedRealtime() - timeStart;
5702     }
5703
5704     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5705             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5706             boolean useTombstonedForJavaTraces) {
5707
5708         // We don't need any sort of inotify based monitoring when we're dumping traces via
5709         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5710         // control of all writes to the file in question.
5711         final DumpStackFileObserver observer;
5712         if (useTombstonedForJavaTraces) {
5713             observer = null;
5714         } else {
5715             // Use a FileObserver to detect when traces finish writing.
5716             // The order of traces is considered important to maintain for legibility.
5717             observer = new DumpStackFileObserver(tracesFile);
5718         }
5719
5720         // We must complete all stack dumps within 20 seconds.
5721         long remainingTime = 20 * 1000;
5722         try {
5723             if (observer != null) {
5724                 observer.startWatching();
5725             }
5726
5727             // First collect all of the stacks of the most important pids.
5728             if (firstPids != null) {
5729                 int num = firstPids.size();
5730                 for (int i = 0; i < num; i++) {
5731                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5732                             + firstPids.get(i));
5733                     final long timeTaken;
5734                     if (useTombstonedForJavaTraces) {
5735                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5736                     } else {
5737                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5738                     }
5739
5740                     remainingTime -= timeTaken;
5741                     if (remainingTime <= 0) {
5742                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5743                             "); deadline exceeded.");
5744                         return;
5745                     }
5746
5747                     if (DEBUG_ANR) {
5748                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5749                     }
5750                 }
5751             }
5752
5753             // Next collect the stacks of the native pids
5754             if (nativePids != null) {
5755                 for (int pid : nativePids) {
5756                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5757                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5758
5759                     final long start = SystemClock.elapsedRealtime();
5760                     Debug.dumpNativeBacktraceToFileTimeout(
5761                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5762                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5763
5764                     remainingTime -= timeTaken;
5765                     if (remainingTime <= 0) {
5766                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5767                             "); deadline exceeded.");
5768                         return;
5769                     }
5770
5771                     if (DEBUG_ANR) {
5772                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5773                     }
5774                 }
5775             }
5776
5777             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5778             if (extraPids != null) {
5779                 for (int pid : extraPids) {
5780                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5781
5782                     final long timeTaken;
5783                     if (useTombstonedForJavaTraces) {
5784                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5785                     } else {
5786                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5787                     }
5788
5789                     remainingTime -= timeTaken;
5790                     if (remainingTime <= 0) {
5791                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5792                                 "); deadline exceeded.");
5793                         return;
5794                     }
5795
5796                     if (DEBUG_ANR) {
5797                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5798                     }
5799                 }
5800             }
5801         } finally {
5802             if (observer != null) {
5803                 observer.stopWatching();
5804             }
5805         }
5806     }
5807
5808     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5809         if (true || Build.IS_USER) {
5810             return;
5811         }
5812         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5813         if (tracesPath == null || tracesPath.length() == 0) {
5814             return;
5815         }
5816
5817         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5818         StrictMode.allowThreadDiskWrites();
5819         try {
5820             final File tracesFile = new File(tracesPath);
5821             final File tracesDir = tracesFile.getParentFile();
5822             final File tracesTmp = new File(tracesDir, "__tmp__");
5823             try {
5824                 if (tracesFile.exists()) {
5825                     tracesTmp.delete();
5826                     tracesFile.renameTo(tracesTmp);
5827                 }
5828                 StringBuilder sb = new StringBuilder();
5829                 Time tobj = new Time();
5830                 tobj.set(System.currentTimeMillis());
5831                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5832                 sb.append(": ");
5833                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5834                 sb.append(" since ");
5835                 sb.append(msg);
5836                 FileOutputStream fos = new FileOutputStream(tracesFile);
5837                 fos.write(sb.toString().getBytes());
5838                 if (app == null) {
5839                     fos.write("\n*** No application process!".getBytes());
5840                 }
5841                 fos.close();
5842                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5843             } catch (IOException e) {
5844                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5845                 return;
5846             }
5847
5848             if (app != null) {
5849                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5850                 firstPids.add(app.pid);
5851                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5852             }
5853
5854             File lastTracesFile = null;
5855             File curTracesFile = null;
5856             for (int i=9; i>=0; i--) {
5857                 String name = String.format(Locale.US, "slow%02d.txt", i);
5858                 curTracesFile = new File(tracesDir, name);
5859                 if (curTracesFile.exists()) {
5860                     if (lastTracesFile != null) {
5861                         curTracesFile.renameTo(lastTracesFile);
5862                     } else {
5863                         curTracesFile.delete();
5864                     }
5865                 }
5866                 lastTracesFile = curTracesFile;
5867             }
5868             tracesFile.renameTo(curTracesFile);
5869             if (tracesTmp.exists()) {
5870                 tracesTmp.renameTo(tracesFile);
5871             }
5872         } finally {
5873             StrictMode.setThreadPolicy(oldPolicy);
5874         }
5875     }
5876
5877     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5878         if (!mLaunchWarningShown) {
5879             mLaunchWarningShown = true;
5880             mUiHandler.post(new Runnable() {
5881                 @Override
5882                 public void run() {
5883                     synchronized (ActivityManagerService.this) {
5884                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5885                         d.show();
5886                         mUiHandler.postDelayed(new Runnable() {
5887                             @Override
5888                             public void run() {
5889                                 synchronized (ActivityManagerService.this) {
5890                                     d.dismiss();
5891                                     mLaunchWarningShown = false;
5892                                 }
5893                             }
5894                         }, 4000);
5895                     }
5896                 }
5897             });
5898         }
5899     }
5900
5901     @Override
5902     public boolean clearApplicationUserData(final String packageName,
5903             final IPackageDataObserver observer, int userId) {
5904         enforceNotIsolatedCaller("clearApplicationUserData");
5905         int uid = Binder.getCallingUid();
5906         int pid = Binder.getCallingPid();
5907         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5908                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5909
5910         final ApplicationInfo appInfo;
5911         final boolean isInstantApp;
5912
5913         long callingId = Binder.clearCallingIdentity();
5914         try {
5915             IPackageManager pm = AppGlobals.getPackageManager();
5916             synchronized(this) {
5917                 // Instant packages are not protected
5918                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5919                         resolvedUserId, packageName)) {
5920                     throw new SecurityException(
5921                             "Cannot clear data for a protected package: " + packageName);
5922                 }
5923
5924                 ApplicationInfo applicationInfo = null;
5925                 try {
5926                     applicationInfo = pm.getApplicationInfo(packageName,
5927                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5928                 } catch (RemoteException e) {
5929                     /* ignore */
5930                 }
5931                 appInfo = applicationInfo;
5932
5933                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5934
5935                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5936                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5937                     throw new SecurityException("PID " + pid + " does not have permission "
5938                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5939                             + " of package " + packageName);
5940                 }
5941
5942                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5943                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
5944                 final boolean isUninstalledAppWithoutInstantMetadata =
5945                         (appInfo == null && !hasInstantMetadata);
5946                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5947                         || hasInstantMetadata;
5948                 final boolean canAccessInstantApps = checkComponentPermission(
5949                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5950                         == PackageManager.PERMISSION_GRANTED;
5951
5952                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5953                         && !canAccessInstantApps)) {
5954                     Slog.w(TAG, "Invalid packageName: " + packageName);
5955                     if (observer != null) {
5956                         try {
5957                             observer.onRemoveCompleted(packageName, false);
5958                         } catch (RemoteException e) {
5959                             Slog.i(TAG, "Observer no longer exists.");
5960                         }
5961                     }
5962                     return false;
5963                 }
5964
5965                 if (appInfo != null) {
5966                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5967                     // Remove all tasks match the cleared application package and user
5968                     for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5969                         final TaskRecord tr = mRecentTasks.get(i);
5970                         final String taskPackageName =
5971                                 tr.getBaseIntent().getComponent().getPackageName();
5972                         if (tr.userId != resolvedUserId) continue;
5973                         if (!taskPackageName.equals(packageName)) continue;
5974                         mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5975                                 REMOVE_FROM_RECENTS);
5976                     }
5977                 }
5978             }
5979
5980             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5981                 @Override
5982                 public void onRemoveCompleted(String packageName, boolean succeeded)
5983                         throws RemoteException {
5984                     if (appInfo != null) {
5985                         synchronized (ActivityManagerService.this) {
5986                             finishForceStopPackageLocked(packageName, appInfo.uid);
5987                         }
5988                     }
5989                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5990                             Uri.fromParts("package", packageName, null));
5991                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
5992                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
5993                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
5994                     if (isInstantApp) {
5995                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
5996                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
5997                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
5998                                 resolvedUserId);
5999                     } else {
6000                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6001                                 null, null, null, null, false, false, resolvedUserId);
6002                     }
6003
6004                     if (observer != null) {
6005                         observer.onRemoveCompleted(packageName, succeeded);
6006                     }
6007                 }
6008             };
6009
6010             try {
6011                 // Clear application user data
6012                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6013
6014                 if (appInfo != null) {
6015                     synchronized (this) {
6016                         // Remove all permissions granted from/to this package
6017                         removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6018                     }
6019
6020                     // Reset notification settings.
6021                     INotificationManager inm = NotificationManager.getService();
6022                     inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6023                 }
6024             } catch (RemoteException e) {
6025             }
6026         } finally {
6027             Binder.restoreCallingIdentity(callingId);
6028         }
6029         return true;
6030     }
6031
6032     @Override
6033     public void killBackgroundProcesses(final String packageName, int userId) {
6034         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6035                 != PackageManager.PERMISSION_GRANTED &&
6036                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6037                         != PackageManager.PERMISSION_GRANTED) {
6038             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6039                     + Binder.getCallingPid()
6040                     + ", uid=" + Binder.getCallingUid()
6041                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6042             Slog.w(TAG, msg);
6043             throw new SecurityException(msg);
6044         }
6045
6046         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6047                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6048         long callingId = Binder.clearCallingIdentity();
6049         try {
6050             IPackageManager pm = AppGlobals.getPackageManager();
6051             synchronized(this) {
6052                 int appId = -1;
6053                 try {
6054                     appId = UserHandle.getAppId(
6055                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6056                 } catch (RemoteException e) {
6057                 }
6058                 if (appId == -1) {
6059                     Slog.w(TAG, "Invalid packageName: " + packageName);
6060                     return;
6061                 }
6062                 killPackageProcessesLocked(packageName, appId, userId,
6063                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6064             }
6065         } finally {
6066             Binder.restoreCallingIdentity(callingId);
6067         }
6068     }
6069
6070     @Override
6071     public void killAllBackgroundProcesses() {
6072         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6073                 != PackageManager.PERMISSION_GRANTED) {
6074             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6075                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6076                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6077             Slog.w(TAG, msg);
6078             throw new SecurityException(msg);
6079         }
6080
6081         final long callingId = Binder.clearCallingIdentity();
6082         try {
6083             synchronized (this) {
6084                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6085                 final int NP = mProcessNames.getMap().size();
6086                 for (int ip = 0; ip < NP; ip++) {
6087                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6088                     final int NA = apps.size();
6089                     for (int ia = 0; ia < NA; ia++) {
6090                         final ProcessRecord app = apps.valueAt(ia);
6091                         if (app.persistent) {
6092                             // We don't kill persistent processes.
6093                             continue;
6094                         }
6095                         if (app.removed) {
6096                             procs.add(app);
6097                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6098                             app.removed = true;
6099                             procs.add(app);
6100                         }
6101                     }
6102                 }
6103
6104                 final int N = procs.size();
6105                 for (int i = 0; i < N; i++) {
6106                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6107                 }
6108
6109                 mAllowLowerMemLevel = true;
6110
6111                 updateOomAdjLocked();
6112                 doLowMemReportIfNeededLocked(null);
6113             }
6114         } finally {
6115             Binder.restoreCallingIdentity(callingId);
6116         }
6117     }
6118
6119     /**
6120      * Kills all background processes, except those matching any of the
6121      * specified properties.
6122      *
6123      * @param minTargetSdk the target SDK version at or above which to preserve
6124      *                     processes, or {@code -1} to ignore the target SDK
6125      * @param maxProcState the process state at or below which to preserve
6126      *                     processes, or {@code -1} to ignore the process state
6127      */
6128     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6129         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6130                 != PackageManager.PERMISSION_GRANTED) {
6131             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6132                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6133                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6134             Slog.w(TAG, msg);
6135             throw new SecurityException(msg);
6136         }
6137
6138         final long callingId = Binder.clearCallingIdentity();
6139         try {
6140             synchronized (this) {
6141                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6142                 final int NP = mProcessNames.getMap().size();
6143                 for (int ip = 0; ip < NP; ip++) {
6144                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6145                     final int NA = apps.size();
6146                     for (int ia = 0; ia < NA; ia++) {
6147                         final ProcessRecord app = apps.valueAt(ia);
6148                         if (app.removed) {
6149                             procs.add(app);
6150                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6151                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6152                             app.removed = true;
6153                             procs.add(app);
6154                         }
6155                     }
6156                 }
6157
6158                 final int N = procs.size();
6159                 for (int i = 0; i < N; i++) {
6160                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6161                 }
6162             }
6163         } finally {
6164             Binder.restoreCallingIdentity(callingId);
6165         }
6166     }
6167
6168     @Override
6169     public void forceStopPackage(final String packageName, int userId) {
6170         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6171                 != PackageManager.PERMISSION_GRANTED) {
6172             String msg = "Permission Denial: forceStopPackage() from pid="
6173                     + Binder.getCallingPid()
6174                     + ", uid=" + Binder.getCallingUid()
6175                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6176             Slog.w(TAG, msg);
6177             throw new SecurityException(msg);
6178         }
6179         final int callingPid = Binder.getCallingPid();
6180         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6181                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6182         long callingId = Binder.clearCallingIdentity();
6183         try {
6184             IPackageManager pm = AppGlobals.getPackageManager();
6185             synchronized(this) {
6186                 int[] users = userId == UserHandle.USER_ALL
6187                         ? mUserController.getUsers() : new int[] { userId };
6188                 for (int user : users) {
6189                     int pkgUid = -1;
6190                     try {
6191                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6192                                 user);
6193                     } catch (RemoteException e) {
6194                     }
6195                     if (pkgUid == -1) {
6196                         Slog.w(TAG, "Invalid packageName: " + packageName);
6197                         continue;
6198                     }
6199                     try {
6200                         pm.setPackageStoppedState(packageName, true, user);
6201                     } catch (RemoteException e) {
6202                     } catch (IllegalArgumentException e) {
6203                         Slog.w(TAG, "Failed trying to unstop package "
6204                                 + packageName + ": " + e);
6205                     }
6206                     if (mUserController.isUserRunningLocked(user, 0)) {
6207                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6208                         finishForceStopPackageLocked(packageName, pkgUid);
6209                     }
6210                 }
6211             }
6212         } finally {
6213             Binder.restoreCallingIdentity(callingId);
6214         }
6215     }
6216
6217     @Override
6218     public void addPackageDependency(String packageName) {
6219         synchronized (this) {
6220             int callingPid = Binder.getCallingPid();
6221             if (callingPid == myPid()) {
6222                 //  Yeah, um, no.
6223                 return;
6224             }
6225             ProcessRecord proc;
6226             synchronized (mPidsSelfLocked) {
6227                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6228             }
6229             if (proc != null) {
6230                 if (proc.pkgDeps == null) {
6231                     proc.pkgDeps = new ArraySet<String>(1);
6232                 }
6233                 proc.pkgDeps.add(packageName);
6234             }
6235         }
6236     }
6237
6238     /*
6239      * The pkg name and app id have to be specified.
6240      */
6241     @Override
6242     public void killApplication(String pkg, int appId, int userId, String reason) {
6243         if (pkg == null) {
6244             return;
6245         }
6246         // Make sure the uid is valid.
6247         if (appId < 0) {
6248             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6249             return;
6250         }
6251         int callerUid = Binder.getCallingUid();
6252         // Only the system server can kill an application
6253         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6254             // Post an aysnc message to kill the application
6255             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6256             msg.arg1 = appId;
6257             msg.arg2 = userId;
6258             Bundle bundle = new Bundle();
6259             bundle.putString("pkg", pkg);
6260             bundle.putString("reason", reason);
6261             msg.obj = bundle;
6262             mHandler.sendMessage(msg);
6263         } else {
6264             throw new SecurityException(callerUid + " cannot kill pkg: " +
6265                     pkg);
6266         }
6267     }
6268
6269     @Override
6270     public void closeSystemDialogs(String reason) {
6271         enforceNotIsolatedCaller("closeSystemDialogs");
6272
6273         final int pid = Binder.getCallingPid();
6274         final int uid = Binder.getCallingUid();
6275         final long origId = Binder.clearCallingIdentity();
6276         try {
6277             synchronized (this) {
6278                 // Only allow this from foreground processes, so that background
6279                 // applications can't abuse it to prevent system UI from being shown.
6280                 if (uid >= FIRST_APPLICATION_UID) {
6281                     ProcessRecord proc;
6282                     synchronized (mPidsSelfLocked) {
6283                         proc = mPidsSelfLocked.get(pid);
6284                     }
6285                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6286                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6287                                 + " from background process " + proc);
6288                         return;
6289                     }
6290                 }
6291                 closeSystemDialogsLocked(reason);
6292             }
6293         } finally {
6294             Binder.restoreCallingIdentity(origId);
6295         }
6296     }
6297
6298     void closeSystemDialogsLocked(String reason) {
6299         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6300         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6301                 | Intent.FLAG_RECEIVER_FOREGROUND);
6302         if (reason != null) {
6303             intent.putExtra("reason", reason);
6304         }
6305         mWindowManager.closeSystemDialogs(reason);
6306
6307         mStackSupervisor.closeSystemDialogsLocked();
6308
6309         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6310                 AppOpsManager.OP_NONE, null, false, false,
6311                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6312     }
6313
6314     @Override
6315     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6316         enforceNotIsolatedCaller("getProcessMemoryInfo");
6317         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6318         for (int i=pids.length-1; i>=0; i--) {
6319             ProcessRecord proc;
6320             int oomAdj;
6321             synchronized (this) {
6322                 synchronized (mPidsSelfLocked) {
6323                     proc = mPidsSelfLocked.get(pids[i]);
6324                     oomAdj = proc != null ? proc.setAdj : 0;
6325                 }
6326             }
6327             infos[i] = new Debug.MemoryInfo();
6328             Debug.getMemoryInfo(pids[i], infos[i]);
6329             if (proc != null) {
6330                 synchronized (this) {
6331                     if (proc.thread != null && proc.setAdj == oomAdj) {
6332                         // Record this for posterity if the process has been stable.
6333                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6334                                 infos[i].getTotalUss(), false, proc.pkgList);
6335                     }
6336                 }
6337             }
6338         }
6339         return infos;
6340     }
6341
6342     @Override
6343     public long[] getProcessPss(int[] pids) {
6344         enforceNotIsolatedCaller("getProcessPss");
6345         long[] pss = new long[pids.length];
6346         for (int i=pids.length-1; i>=0; i--) {
6347             ProcessRecord proc;
6348             int oomAdj;
6349             synchronized (this) {
6350                 synchronized (mPidsSelfLocked) {
6351                     proc = mPidsSelfLocked.get(pids[i]);
6352                     oomAdj = proc != null ? proc.setAdj : 0;
6353                 }
6354             }
6355             long[] tmpUss = new long[1];
6356             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6357             if (proc != null) {
6358                 synchronized (this) {
6359                     if (proc.thread != null && proc.setAdj == oomAdj) {
6360                         // Record this for posterity if the process has been stable.
6361                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6362                     }
6363                 }
6364             }
6365         }
6366         return pss;
6367     }
6368
6369     @Override
6370     public void killApplicationProcess(String processName, int uid) {
6371         if (processName == null) {
6372             return;
6373         }
6374
6375         int callerUid = Binder.getCallingUid();
6376         // Only the system server can kill an application
6377         if (callerUid == SYSTEM_UID) {
6378             synchronized (this) {
6379                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6380                 if (app != null && app.thread != null) {
6381                     try {
6382                         app.thread.scheduleSuicide();
6383                     } catch (RemoteException e) {
6384                         // If the other end already died, then our work here is done.
6385                     }
6386                 } else {
6387                     Slog.w(TAG, "Process/uid not found attempting kill of "
6388                             + processName + " / " + uid);
6389                 }
6390             }
6391         } else {
6392             throw new SecurityException(callerUid + " cannot kill app process: " +
6393                     processName);
6394         }
6395     }
6396
6397     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6398         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6399                 false, true, false, false, UserHandle.getUserId(uid), reason);
6400     }
6401
6402     private void finishForceStopPackageLocked(final String packageName, int uid) {
6403         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6404                 Uri.fromParts("package", packageName, null));
6405         if (!mProcessesReady) {
6406             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6407                     | Intent.FLAG_RECEIVER_FOREGROUND);
6408         }
6409         intent.putExtra(Intent.EXTRA_UID, uid);
6410         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6411         broadcastIntentLocked(null, null, intent,
6412                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6413                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6414     }
6415
6416
6417     private final boolean killPackageProcessesLocked(String packageName, int appId,
6418             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6419             boolean doit, boolean evenPersistent, String reason) {
6420         ArrayList<ProcessRecord> procs = new ArrayList<>();
6421
6422         // Remove all processes this package may have touched: all with the
6423         // same UID (except for the system or root user), and all whose name
6424         // matches the package name.
6425         final int NP = mProcessNames.getMap().size();
6426         for (int ip=0; ip<NP; ip++) {
6427             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6428             final int NA = apps.size();
6429             for (int ia=0; ia<NA; ia++) {
6430                 ProcessRecord app = apps.valueAt(ia);
6431                 if (app.persistent && !evenPersistent) {
6432                     // we don't kill persistent processes
6433                     continue;
6434                 }
6435                 if (app.removed) {
6436                     if (doit) {
6437                         procs.add(app);
6438                     }
6439                     continue;
6440                 }
6441
6442                 // Skip process if it doesn't meet our oom adj requirement.
6443                 if (app.setAdj < minOomAdj) {
6444                     continue;
6445                 }
6446
6447                 // If no package is specified, we call all processes under the
6448                 // give user id.
6449                 if (packageName == null) {
6450                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6451                         continue;
6452                     }
6453                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6454                         continue;
6455                     }
6456                 // Package has been specified, we want to hit all processes
6457                 // that match it.  We need to qualify this by the processes
6458                 // that are running under the specified app and user ID.
6459                 } else {
6460                     final boolean isDep = app.pkgDeps != null
6461                             && app.pkgDeps.contains(packageName);
6462                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6463                         continue;
6464                     }
6465                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6466                         continue;
6467                     }
6468                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6469                         continue;
6470                     }
6471                 }
6472
6473                 // Process has passed all conditions, kill it!
6474                 if (!doit) {
6475                     return true;
6476                 }
6477                 app.removed = true;
6478                 procs.add(app);
6479             }
6480         }
6481
6482         int N = procs.size();
6483         for (int i=0; i<N; i++) {
6484             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6485         }
6486         updateOomAdjLocked();
6487         return N > 0;
6488     }
6489
6490     private void cleanupDisabledPackageComponentsLocked(
6491             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6492
6493         Set<String> disabledClasses = null;
6494         boolean packageDisabled = false;
6495         IPackageManager pm = AppGlobals.getPackageManager();
6496
6497         if (changedClasses == null) {
6498             // Nothing changed...
6499             return;
6500         }
6501
6502         // Determine enable/disable state of the package and its components.
6503         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6504         for (int i = changedClasses.length - 1; i >= 0; i--) {
6505             final String changedClass = changedClasses[i];
6506
6507             if (changedClass.equals(packageName)) {
6508                 try {
6509                     // Entire package setting changed
6510                     enabled = pm.getApplicationEnabledSetting(packageName,
6511                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6512                 } catch (Exception e) {
6513                     // No such package/component; probably racing with uninstall.  In any
6514                     // event it means we have nothing further to do here.
6515                     return;
6516                 }
6517                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6518                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6519                 if (packageDisabled) {
6520                     // Entire package is disabled.
6521                     // No need to continue to check component states.
6522                     disabledClasses = null;
6523                     break;
6524                 }
6525             } else {
6526                 try {
6527                     enabled = pm.getComponentEnabledSetting(
6528                             new ComponentName(packageName, changedClass),
6529                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6530                 } catch (Exception e) {
6531                     // As above, probably racing with uninstall.
6532                     return;
6533                 }
6534                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6535                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6536                     if (disabledClasses == null) {
6537                         disabledClasses = new ArraySet<>(changedClasses.length);
6538                     }
6539                     disabledClasses.add(changedClass);
6540                 }
6541             }
6542         }
6543
6544         if (!packageDisabled && disabledClasses == null) {
6545             // Nothing to do here...
6546             return;
6547         }
6548
6549         // Clean-up disabled activities.
6550         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6551                 packageName, disabledClasses, true, false, userId) && mBooted) {
6552             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6553             mStackSupervisor.scheduleIdleLocked();
6554         }
6555
6556         // Clean-up disabled tasks
6557         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6558
6559         // Clean-up disabled services.
6560         mServices.bringDownDisabledPackageServicesLocked(
6561                 packageName, disabledClasses, userId, false, killProcess, true);
6562
6563         // Clean-up disabled providers.
6564         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6565         mProviderMap.collectPackageProvidersLocked(
6566                 packageName, disabledClasses, true, false, userId, providers);
6567         for (int i = providers.size() - 1; i >= 0; i--) {
6568             removeDyingProviderLocked(null, providers.get(i), true);
6569         }
6570
6571         // Clean-up disabled broadcast receivers.
6572         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6573             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6574                     packageName, disabledClasses, userId, true);
6575         }
6576
6577     }
6578
6579     final boolean clearBroadcastQueueForUserLocked(int userId) {
6580         boolean didSomething = false;
6581         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6582             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6583                     null, null, userId, true);
6584         }
6585         return didSomething;
6586     }
6587
6588     final boolean forceStopPackageLocked(String packageName, int appId,
6589             boolean callerWillRestart, boolean purgeCache, boolean doit,
6590             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6591         int i;
6592
6593         if (userId == UserHandle.USER_ALL && packageName == null) {
6594             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6595         }
6596
6597         if (appId < 0 && packageName != null) {
6598             try {
6599                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6600                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6601             } catch (RemoteException e) {
6602             }
6603         }
6604
6605         if (doit) {
6606             if (packageName != null) {
6607                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6608                         + " user=" + userId + ": " + reason);
6609             } else {
6610                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6611             }
6612
6613             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6614         }
6615
6616         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6617                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6618                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6619
6620         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6621
6622         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6623                 packageName, null, doit, evenPersistent, userId)) {
6624             if (!doit) {
6625                 return true;
6626             }
6627             didSomething = true;
6628         }
6629
6630         if (mServices.bringDownDisabledPackageServicesLocked(
6631                 packageName, null, userId, evenPersistent, true, doit)) {
6632             if (!doit) {
6633                 return true;
6634             }
6635             didSomething = true;
6636         }
6637
6638         if (packageName == null) {
6639             // Remove all sticky broadcasts from this user.
6640             mStickyBroadcasts.remove(userId);
6641         }
6642
6643         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6644         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6645                 userId, providers)) {
6646             if (!doit) {
6647                 return true;
6648             }
6649             didSomething = true;
6650         }
6651         for (i = providers.size() - 1; i >= 0; i--) {
6652             removeDyingProviderLocked(null, providers.get(i), true);
6653         }
6654
6655         // Remove transient permissions granted from/to this package/user
6656         removeUriPermissionsForPackageLocked(packageName, userId, false);
6657
6658         if (doit) {
6659             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6660                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6661                         packageName, null, userId, doit);
6662             }
6663         }
6664
6665         if (packageName == null || uninstalling) {
6666             // Remove pending intents.  For now we only do this when force
6667             // stopping users, because we have some problems when doing this
6668             // for packages -- app widgets are not currently cleaned up for
6669             // such packages, so they can be left with bad pending intents.
6670             if (mIntentSenderRecords.size() > 0) {
6671                 Iterator<WeakReference<PendingIntentRecord>> it
6672                         = mIntentSenderRecords.values().iterator();
6673                 while (it.hasNext()) {
6674                     WeakReference<PendingIntentRecord> wpir = it.next();
6675                     if (wpir == null) {
6676                         it.remove();
6677                         continue;
6678                     }
6679                     PendingIntentRecord pir = wpir.get();
6680                     if (pir == null) {
6681                         it.remove();
6682                         continue;
6683                     }
6684                     if (packageName == null) {
6685                         // Stopping user, remove all objects for the user.
6686                         if (pir.key.userId != userId) {
6687                             // Not the same user, skip it.
6688                             continue;
6689                         }
6690                     } else {
6691                         if (UserHandle.getAppId(pir.uid) != appId) {
6692                             // Different app id, skip it.
6693                             continue;
6694                         }
6695                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6696                             // Different user, skip it.
6697                             continue;
6698                         }
6699                         if (!pir.key.packageName.equals(packageName)) {
6700                             // Different package, skip it.
6701                             continue;
6702                         }
6703                     }
6704                     if (!doit) {
6705                         return true;
6706                     }
6707                     didSomething = true;
6708                     it.remove();
6709                     makeIntentSenderCanceledLocked(pir);
6710                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6711                         pir.key.activity.pendingResults.remove(pir.ref);
6712                     }
6713                 }
6714             }
6715         }
6716
6717         if (doit) {
6718             if (purgeCache && packageName != null) {
6719                 AttributeCache ac = AttributeCache.instance();
6720                 if (ac != null) {
6721                     ac.removePackage(packageName);
6722                 }
6723             }
6724             if (mBooted) {
6725                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6726                 mStackSupervisor.scheduleIdleLocked();
6727             }
6728         }
6729
6730         return didSomething;
6731     }
6732
6733     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6734         return removeProcessNameLocked(name, uid, null);
6735     }
6736
6737     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6738             final ProcessRecord expecting) {
6739         ProcessRecord old = mProcessNames.get(name, uid);
6740         // Only actually remove when the currently recorded value matches the
6741         // record that we expected; if it doesn't match then we raced with a
6742         // newly created process and we don't want to destroy the new one.
6743         if ((expecting == null) || (old == expecting)) {
6744             mProcessNames.remove(name, uid);
6745         }
6746         if (old != null && old.uidRecord != null) {
6747             old.uidRecord.numProcs--;
6748             if (old.uidRecord.numProcs == 0) {
6749                 // No more processes using this uid, tell clients it is gone.
6750                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6751                         "No more processes in " + old.uidRecord);
6752                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6753                 EventLogTags.writeAmUidStopped(uid);
6754                 mActiveUids.remove(uid);
6755                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6756             }
6757             old.uidRecord = null;
6758         }
6759         mIsolatedProcesses.remove(uid);
6760         return old;
6761     }
6762
6763     private final void addProcessNameLocked(ProcessRecord proc) {
6764         // We shouldn't already have a process under this name, but just in case we
6765         // need to clean up whatever may be there now.
6766         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6767         if (old == proc && proc.persistent) {
6768             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6769             Slog.w(TAG, "Re-adding persistent process " + proc);
6770         } else if (old != null) {
6771             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6772         }
6773         UidRecord uidRec = mActiveUids.get(proc.uid);
6774         if (uidRec == null) {
6775             uidRec = new UidRecord(proc.uid);
6776             // This is the first appearance of the uid, report it now!
6777             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6778                     "Creating new process uid: " + uidRec);
6779             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6780                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6781                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6782             }
6783             uidRec.updateHasInternetPermission();
6784             mActiveUids.put(proc.uid, uidRec);
6785             EventLogTags.writeAmUidRunning(uidRec.uid);
6786             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6787         }
6788         proc.uidRecord = uidRec;
6789
6790         // Reset render thread tid if it was already set, so new process can set it again.
6791         proc.renderThreadTid = 0;
6792         uidRec.numProcs++;
6793         mProcessNames.put(proc.processName, proc.uid, proc);
6794         if (proc.isolated) {
6795             mIsolatedProcesses.put(proc.uid, proc);
6796         }
6797     }
6798
6799     boolean removeProcessLocked(ProcessRecord app,
6800             boolean callerWillRestart, boolean allowRestart, String reason) {
6801         final String name = app.processName;
6802         final int uid = app.uid;
6803         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6804             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6805
6806         ProcessRecord old = mProcessNames.get(name, uid);
6807         if (old != app) {
6808             // This process is no longer active, so nothing to do.
6809             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6810             return false;
6811         }
6812         removeProcessNameLocked(name, uid);
6813         if (mHeavyWeightProcess == app) {
6814             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6815                     mHeavyWeightProcess.userId, 0));
6816             mHeavyWeightProcess = null;
6817         }
6818         boolean needRestart = false;
6819         if (app.pid > 0 && app.pid != MY_PID) {
6820             int pid = app.pid;
6821             synchronized (mPidsSelfLocked) {
6822                 mPidsSelfLocked.remove(pid);
6823                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6824             }
6825             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6826             boolean willRestart = false;
6827             if (app.persistent && !app.isolated) {
6828                 if (!callerWillRestart) {
6829                     willRestart = true;
6830                 } else {
6831                     needRestart = true;
6832                 }
6833             }
6834             app.kill(reason, true);
6835             if (app.isolated) {
6836                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6837                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6838             }
6839             handleAppDiedLocked(app, willRestart, allowRestart);
6840             if (willRestart) {
6841                 removeLruProcessLocked(app);
6842                 addAppLocked(app.info, null, false, null /* ABI override */);
6843             }
6844         } else {
6845             mRemovedProcesses.add(app);
6846         }
6847
6848         return needRestart;
6849     }
6850
6851     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6852         cleanupAppInLaunchingProvidersLocked(app, true);
6853         removeProcessLocked(app, false, true, "timeout publishing content providers");
6854     }
6855
6856     private final void processStartTimedOutLocked(ProcessRecord app) {
6857         final int pid = app.pid;
6858         boolean gone = false;
6859         synchronized (mPidsSelfLocked) {
6860             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6861             if (knownApp != null && knownApp.thread == null) {
6862                 mPidsSelfLocked.remove(pid);
6863                 gone = true;
6864             }
6865         }
6866
6867         if (gone) {
6868             Slog.w(TAG, "Process " + app + " failed to attach");
6869             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6870                     pid, app.uid, app.processName);
6871             removeProcessNameLocked(app.processName, app.uid);
6872             if (mHeavyWeightProcess == app) {
6873                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6874                         mHeavyWeightProcess.userId, 0));
6875                 mHeavyWeightProcess = null;
6876             }
6877             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6878             // Take care of any launching providers waiting for this process.
6879             cleanupAppInLaunchingProvidersLocked(app, true);
6880             // Take care of any services that are waiting for the process.
6881             mServices.processStartTimedOutLocked(app);
6882             app.kill("start timeout", true);
6883             if (app.isolated) {
6884                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6885             }
6886             removeLruProcessLocked(app);
6887             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6888                 Slog.w(TAG, "Unattached app died before backup, skipping");
6889                 mHandler.post(new Runnable() {
6890                 @Override
6891                     public void run(){
6892                         try {
6893                             IBackupManager bm = IBackupManager.Stub.asInterface(
6894                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6895                             bm.agentDisconnected(app.info.packageName);
6896                         } catch (RemoteException e) {
6897                             // Can't happen; the backup manager is local
6898                         }
6899                     }
6900                 });
6901             }
6902             if (isPendingBroadcastProcessLocked(pid)) {
6903                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6904                 skipPendingBroadcastLocked(pid);
6905             }
6906         } else {
6907             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6908         }
6909     }
6910
6911     private final boolean attachApplicationLocked(IApplicationThread thread,
6912             int pid) {
6913
6914         // Find the application record that is being attached...  either via
6915         // the pid if we are running in multiple processes, or just pull the
6916         // next app record if we are emulating process with anonymous threads.
6917         ProcessRecord app;
6918         long startTime = SystemClock.uptimeMillis();
6919         if (pid != MY_PID && pid >= 0) {
6920             synchronized (mPidsSelfLocked) {
6921                 app = mPidsSelfLocked.get(pid);
6922             }
6923         } else {
6924             app = null;
6925         }
6926
6927         if (app == null) {
6928             Slog.w(TAG, "No pending application record for pid " + pid
6929                     + " (IApplicationThread " + thread + "); dropping process");
6930             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6931             if (pid > 0 && pid != MY_PID) {
6932                 killProcessQuiet(pid);
6933                 //TODO: killProcessGroup(app.info.uid, pid);
6934             } else {
6935                 try {
6936                     thread.scheduleExit();
6937                 } catch (Exception e) {
6938                     // Ignore exceptions.
6939                 }
6940             }
6941             return false;
6942         }
6943
6944         // If this application record is still attached to a previous
6945         // process, clean it up now.
6946         if (app.thread != null) {
6947             handleAppDiedLocked(app, true, true);
6948         }
6949
6950         // Tell the process all about itself.
6951
6952         if (DEBUG_ALL) Slog.v(
6953                 TAG, "Binding process pid " + pid + " to record " + app);
6954
6955         final String processName = app.processName;
6956         try {
6957             AppDeathRecipient adr = new AppDeathRecipient(
6958                     app, pid, thread);
6959             thread.asBinder().linkToDeath(adr, 0);
6960             app.deathRecipient = adr;
6961         } catch (RemoteException e) {
6962             app.resetPackageList(mProcessStats);
6963             startProcessLocked(app, "link fail", processName);
6964             return false;
6965         }
6966
6967         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6968
6969         app.makeActive(thread, mProcessStats);
6970         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6971         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6972         app.forcingToImportant = null;
6973         updateProcessForegroundLocked(app, false, false);
6974         app.hasShownUi = false;
6975         app.debugging = false;
6976         app.cached = false;
6977         app.killedByAm = false;
6978         app.killed = false;
6979
6980
6981         // We carefully use the same state that PackageManager uses for
6982         // filtering, since we use this flag to decide if we need to install
6983         // providers when user is unlocked later
6984         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6985
6986         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6987
6988         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6989         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6990
6991         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6992             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6993             msg.obj = app;
6994             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6995         }
6996
6997         checkTime(startTime, "attachApplicationLocked: before bindApplication");
6998
6999         if (!normalMode) {
7000             Slog.i(TAG, "Launching preboot mode app: " + app);
7001         }
7002
7003         if (DEBUG_ALL) Slog.v(
7004             TAG, "New app record " + app
7005             + " thread=" + thread.asBinder() + " pid=" + pid);
7006         try {
7007             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7008             if (mDebugApp != null && mDebugApp.equals(processName)) {
7009                 testMode = mWaitForDebugger
7010                     ? ApplicationThreadConstants.DEBUG_WAIT
7011                     : ApplicationThreadConstants.DEBUG_ON;
7012                 app.debugging = true;
7013                 if (mDebugTransient) {
7014                     mDebugApp = mOrigDebugApp;
7015                     mWaitForDebugger = mOrigWaitForDebugger;
7016                 }
7017             }
7018
7019             ProfilerInfo profilerInfo = null;
7020             String agent = null;
7021             if (mProfileApp != null && mProfileApp.equals(processName)) {
7022                 mProfileProc = app;
7023                 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7024                         new ProfilerInfo(mProfilerInfo) : null;
7025                 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7026             } else if (app.instr != null && app.instr.mProfileFile != null) {
7027                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7028                         null);
7029             }
7030
7031             boolean enableTrackAllocation = false;
7032             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7033                 enableTrackAllocation = true;
7034                 mTrackAllocationApp = null;
7035             }
7036
7037             // If the app is being launched for restore or full backup, set it up specially
7038             boolean isRestrictedBackupMode = false;
7039             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7040                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7041                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7042                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7043                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7044             }
7045
7046             if (app.instr != null) {
7047                 notifyPackageUse(app.instr.mClass.getPackageName(),
7048                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7049             }
7050             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7051                     + processName + " with config " + getGlobalConfiguration());
7052             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7053             app.compat = compatibilityInfoForPackageLocked(appInfo);
7054
7055             if (profilerInfo != null && profilerInfo.profileFd != null) {
7056                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7057             }
7058
7059             // We deprecated Build.SERIAL and it is not accessible to
7060             // apps that target the v2 security sandbox. Since access to
7061             // the serial is now behind a permission we push down the value.
7062             String buildSerial = appInfo.targetSandboxVersion < 2
7063                     ? sTheRealBuildSerial : Build.UNKNOWN;
7064
7065             // Check if this is a secondary process that should be incorporated into some
7066             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7067             // stuff above because profiling can currently happen only in the primary
7068             // instrumentation process.)
7069             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7070                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7071                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7072                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7073                         if (aInstr.mTargetProcesses.length == 0) {
7074                             // This is the wildcard mode, where every process brought up for
7075                             // the target instrumentation should be included.
7076                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7077                                 app.instr = aInstr;
7078                                 aInstr.mRunningProcesses.add(app);
7079                             }
7080                         } else {
7081                             for (String proc : aInstr.mTargetProcesses) {
7082                                 if (proc.equals(app.processName)) {
7083                                     app.instr = aInstr;
7084                                     aInstr.mRunningProcesses.add(app);
7085                                     break;
7086                                 }
7087                             }
7088                         }
7089                     }
7090                 }
7091             }
7092
7093             // If we were asked to attach an agent on startup, do so now, before we're binding
7094             // application code.
7095             if (agent != null) {
7096                 thread.attachAgent(agent);
7097             }
7098
7099             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7100             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7101             if (app.instr != null) {
7102                 thread.bindApplication(processName, appInfo, providers,
7103                         app.instr.mClass,
7104                         profilerInfo, app.instr.mArguments,
7105                         app.instr.mWatcher,
7106                         app.instr.mUiAutomationConnection, testMode,
7107                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7108                         isRestrictedBackupMode || !normalMode, app.persistent,
7109                         new Configuration(getGlobalConfiguration()), app.compat,
7110                         getCommonServicesLocked(app.isolated),
7111                         mCoreSettingsObserver.getCoreSettingsLocked(),
7112                         buildSerial);
7113             } else {
7114                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7115                         null, null, null, testMode,
7116                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7117                         isRestrictedBackupMode || !normalMode, app.persistent,
7118                         new Configuration(getGlobalConfiguration()), app.compat,
7119                         getCommonServicesLocked(app.isolated),
7120                         mCoreSettingsObserver.getCoreSettingsLocked(),
7121                         buildSerial);
7122             }
7123
7124             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7125             updateLruProcessLocked(app, false, null);
7126             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7127             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7128         } catch (Exception e) {
7129             // todo: Yikes!  What should we do?  For now we will try to
7130             // start another process, but that could easily get us in
7131             // an infinite loop of restarting processes...
7132             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7133
7134             app.resetPackageList(mProcessStats);
7135             app.unlinkDeathRecipient();
7136             startProcessLocked(app, "bind fail", processName);
7137             return false;
7138         }
7139
7140         // Remove this record from the list of starting applications.
7141         mPersistentStartingProcesses.remove(app);
7142         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7143                 "Attach application locked removing on hold: " + app);
7144         mProcessesOnHold.remove(app);
7145
7146         boolean badApp = false;
7147         boolean didSomething = false;
7148
7149         // See if the top visible activity is waiting to run in this process...
7150         if (normalMode) {
7151             try {
7152                 if (mStackSupervisor.attachApplicationLocked(app)) {
7153                     didSomething = true;
7154                 }
7155             } catch (Exception e) {
7156                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7157                 badApp = true;
7158             }
7159         }
7160
7161         // Find any services that should be running in this process...
7162         if (!badApp) {
7163             try {
7164                 didSomething |= mServices.attachApplicationLocked(app, processName);
7165                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7166             } catch (Exception e) {
7167                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7168                 badApp = true;
7169             }
7170         }
7171
7172         // Check if a next-broadcast receiver is in this process...
7173         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7174             try {
7175                 didSomething |= sendPendingBroadcastsLocked(app);
7176                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7177             } catch (Exception e) {
7178                 // If the app died trying to launch the receiver we declare it 'bad'
7179                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7180                 badApp = true;
7181             }
7182         }
7183
7184         // Check whether the next backup agent is in this process...
7185         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7186             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7187                     "New app is backup target, launching agent for " + app);
7188             notifyPackageUse(mBackupTarget.appInfo.packageName,
7189                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7190             try {
7191                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7192                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7193                         mBackupTarget.backupMode);
7194             } catch (Exception e) {
7195                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7196                 badApp = true;
7197             }
7198         }
7199
7200         if (badApp) {
7201             app.kill("error during init", true);
7202             handleAppDiedLocked(app, false, true);
7203             return false;
7204         }
7205
7206         if (!didSomething) {
7207             updateOomAdjLocked();
7208             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7209         }
7210
7211         return true;
7212     }
7213
7214     @Override
7215     public final void attachApplication(IApplicationThread thread) {
7216         synchronized (this) {
7217             int callingPid = Binder.getCallingPid();
7218             final long origId = Binder.clearCallingIdentity();
7219             attachApplicationLocked(thread, callingPid);
7220             Binder.restoreCallingIdentity(origId);
7221         }
7222     }
7223
7224     @Override
7225     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7226         final long origId = Binder.clearCallingIdentity();
7227         synchronized (this) {
7228             ActivityStack stack = ActivityRecord.getStackLocked(token);
7229             if (stack != null) {
7230                 ActivityRecord r =
7231                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7232                                 false /* processPausingActivities */, config);
7233                 if (stopProfiling) {
7234                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7235                         clearProfilerLocked();
7236                     }
7237                 }
7238             }
7239         }
7240         Binder.restoreCallingIdentity(origId);
7241     }
7242
7243     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7244         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7245                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7246     }
7247
7248     void enableScreenAfterBoot() {
7249         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7250                 SystemClock.uptimeMillis());
7251         mWindowManager.enableScreenAfterBoot();
7252
7253         synchronized (this) {
7254             updateEventDispatchingLocked();
7255         }
7256     }
7257
7258     @Override
7259     public void showBootMessage(final CharSequence msg, final boolean always) {
7260         if (Binder.getCallingUid() != myUid()) {
7261             throw new SecurityException();
7262         }
7263         mWindowManager.showBootMessage(msg, always);
7264     }
7265
7266     @Override
7267     public void keyguardGoingAway(int flags) {
7268         enforceNotIsolatedCaller("keyguardGoingAway");
7269         final long token = Binder.clearCallingIdentity();
7270         try {
7271             synchronized (this) {
7272                 mKeyguardController.keyguardGoingAway(flags);
7273             }
7274         } finally {
7275             Binder.restoreCallingIdentity(token);
7276         }
7277     }
7278
7279     /**
7280      * @return whther the keyguard is currently locked.
7281      */
7282     boolean isKeyguardLocked() {
7283         return mKeyguardController.isKeyguardLocked();
7284     }
7285
7286     final void finishBooting() {
7287         synchronized (this) {
7288             if (!mBootAnimationComplete) {
7289                 mCallFinishBooting = true;
7290                 return;
7291             }
7292             mCallFinishBooting = false;
7293         }
7294
7295         ArraySet<String> completedIsas = new ArraySet<String>();
7296         for (String abi : Build.SUPPORTED_ABIS) {
7297             zygoteProcess.establishZygoteConnectionForAbi(abi);
7298             final String instructionSet = VMRuntime.getInstructionSet(abi);
7299             if (!completedIsas.contains(instructionSet)) {
7300                 try {
7301                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7302                 } catch (InstallerException e) {
7303                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7304                             e.getMessage() +")");
7305                 }
7306                 completedIsas.add(instructionSet);
7307             }
7308         }
7309
7310         IntentFilter pkgFilter = new IntentFilter();
7311         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7312         pkgFilter.addDataScheme("package");
7313         mContext.registerReceiver(new BroadcastReceiver() {
7314             @Override
7315             public void onReceive(Context context, Intent intent) {
7316                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7317                 if (pkgs != null) {
7318                     for (String pkg : pkgs) {
7319                         synchronized (ActivityManagerService.this) {
7320                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7321                                     0, "query restart")) {
7322                                 setResultCode(Activity.RESULT_OK);
7323                                 return;
7324                             }
7325                         }
7326                     }
7327                 }
7328             }
7329         }, pkgFilter);
7330
7331         IntentFilter dumpheapFilter = new IntentFilter();
7332         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7333         mContext.registerReceiver(new BroadcastReceiver() {
7334             @Override
7335             public void onReceive(Context context, Intent intent) {
7336                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7337                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7338                 } else {
7339                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7340                 }
7341             }
7342         }, dumpheapFilter);
7343
7344         // Let system services know.
7345         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7346
7347         synchronized (this) {
7348             // Ensure that any processes we had put on hold are now started
7349             // up.
7350             final int NP = mProcessesOnHold.size();
7351             if (NP > 0) {
7352                 ArrayList<ProcessRecord> procs =
7353                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7354                 for (int ip=0; ip<NP; ip++) {
7355                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7356                             + procs.get(ip));
7357                     startProcessLocked(procs.get(ip), "on-hold", null);
7358                 }
7359             }
7360
7361             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7362                 // Start looking for apps that are abusing wake locks.
7363                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7364                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7365                 // Tell anyone interested that we are done booting!
7366                 SystemProperties.set("sys.boot_completed", "1");
7367
7368                 // And trigger dev.bootcomplete if we are not showing encryption progress
7369                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7370                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7371                     SystemProperties.set("dev.bootcomplete", "1");
7372                 }
7373                 mUserController.sendBootCompletedLocked(
7374                         new IIntentReceiver.Stub() {
7375                             @Override
7376                             public void performReceive(Intent intent, int resultCode,
7377                                     String data, Bundle extras, boolean ordered,
7378                                     boolean sticky, int sendingUser) {
7379                                 synchronized (ActivityManagerService.this) {
7380                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7381                                             true, false);
7382                                 }
7383                             }
7384                         });
7385                 scheduleStartProfilesLocked();
7386             }
7387         }
7388     }
7389
7390     @Override
7391     public void bootAnimationComplete() {
7392         final boolean callFinishBooting;
7393         synchronized (this) {
7394             callFinishBooting = mCallFinishBooting;
7395             mBootAnimationComplete = true;
7396         }
7397         if (callFinishBooting) {
7398             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7399             finishBooting();
7400             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7401         }
7402     }
7403
7404     final void ensureBootCompleted() {
7405         boolean booting;
7406         boolean enableScreen;
7407         synchronized (this) {
7408             booting = mBooting;
7409             mBooting = false;
7410             enableScreen = !mBooted;
7411             mBooted = true;
7412         }
7413
7414         if (booting) {
7415             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7416             finishBooting();
7417             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7418         }
7419
7420         if (enableScreen) {
7421             enableScreenAfterBoot();
7422         }
7423     }
7424
7425     @Override
7426     public final void activityResumed(IBinder token) {
7427         final long origId = Binder.clearCallingIdentity();
7428         synchronized(this) {
7429             ActivityRecord.activityResumedLocked(token);
7430             mWindowManager.notifyAppResumedFinished(token);
7431         }
7432         Binder.restoreCallingIdentity(origId);
7433     }
7434
7435     @Override
7436     public final void activityPaused(IBinder token) {
7437         final long origId = Binder.clearCallingIdentity();
7438         synchronized(this) {
7439             ActivityStack stack = ActivityRecord.getStackLocked(token);
7440             if (stack != null) {
7441                 stack.activityPausedLocked(token, false);
7442             }
7443         }
7444         Binder.restoreCallingIdentity(origId);
7445     }
7446
7447     @Override
7448     public final void activityStopped(IBinder token, Bundle icicle,
7449             PersistableBundle persistentState, CharSequence description) {
7450         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7451
7452         // Refuse possible leaked file descriptors
7453         if (icicle != null && icicle.hasFileDescriptors()) {
7454             throw new IllegalArgumentException("File descriptors passed in Bundle");
7455         }
7456
7457         final long origId = Binder.clearCallingIdentity();
7458
7459         synchronized (this) {
7460             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7461             if (r != null) {
7462                 r.activityStoppedLocked(icicle, persistentState, description);
7463             }
7464         }
7465
7466         trimApplications();
7467
7468         Binder.restoreCallingIdentity(origId);
7469     }
7470
7471     @Override
7472     public final void activityDestroyed(IBinder token) {
7473         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7474         synchronized (this) {
7475             ActivityStack stack = ActivityRecord.getStackLocked(token);
7476             if (stack != null) {
7477                 stack.activityDestroyedLocked(token, "activityDestroyed");
7478             }
7479         }
7480     }
7481
7482     @Override
7483     public final void activityRelaunched(IBinder token) {
7484         final long origId = Binder.clearCallingIdentity();
7485         synchronized (this) {
7486             mStackSupervisor.activityRelaunchedLocked(token);
7487         }
7488         Binder.restoreCallingIdentity(origId);
7489     }
7490
7491     @Override
7492     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7493             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7494         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7495                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7496         synchronized (this) {
7497             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7498             if (record == null) {
7499                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7500                         + "found for: " + token);
7501             }
7502             record.setSizeConfigurations(horizontalSizeConfiguration,
7503                     verticalSizeConfigurations, smallestSizeConfigurations);
7504         }
7505     }
7506
7507     @Override
7508     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7509         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7510     }
7511
7512     @Override
7513     public final void notifyEnterAnimationComplete(IBinder token) {
7514         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7515     }
7516
7517     @Override
7518     public String getCallingPackage(IBinder token) {
7519         synchronized (this) {
7520             ActivityRecord r = getCallingRecordLocked(token);
7521             return r != null ? r.info.packageName : null;
7522         }
7523     }
7524
7525     @Override
7526     public ComponentName getCallingActivity(IBinder token) {
7527         synchronized (this) {
7528             ActivityRecord r = getCallingRecordLocked(token);
7529             return r != null ? r.intent.getComponent() : null;
7530         }
7531     }
7532
7533     private ActivityRecord getCallingRecordLocked(IBinder token) {
7534         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7535         if (r == null) {
7536             return null;
7537         }
7538         return r.resultTo;
7539     }
7540
7541     @Override
7542     public ComponentName getActivityClassForToken(IBinder token) {
7543         synchronized(this) {
7544             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7545             if (r == null) {
7546                 return null;
7547             }
7548             return r.intent.getComponent();
7549         }
7550     }
7551
7552     @Override
7553     public String getPackageForToken(IBinder token) {
7554         synchronized(this) {
7555             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7556             if (r == null) {
7557                 return null;
7558             }
7559             return r.packageName;
7560         }
7561     }
7562
7563     @Override
7564     public boolean isRootVoiceInteraction(IBinder token) {
7565         synchronized(this) {
7566             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7567             if (r == null) {
7568                 return false;
7569             }
7570             return r.rootVoiceInteraction;
7571         }
7572     }
7573
7574     @Override
7575     public IIntentSender getIntentSender(int type,
7576             String packageName, IBinder token, String resultWho,
7577             int requestCode, Intent[] intents, String[] resolvedTypes,
7578             int flags, Bundle bOptions, int userId) {
7579         enforceNotIsolatedCaller("getIntentSender");
7580         // Refuse possible leaked file descriptors
7581         if (intents != null) {
7582             if (intents.length < 1) {
7583                 throw new IllegalArgumentException("Intents array length must be >= 1");
7584             }
7585             for (int i=0; i<intents.length; i++) {
7586                 Intent intent = intents[i];
7587                 if (intent != null) {
7588                     if (intent.hasFileDescriptors()) {
7589                         throw new IllegalArgumentException("File descriptors passed in Intent");
7590                     }
7591                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7592                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7593                         throw new IllegalArgumentException(
7594                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7595                     }
7596                     intents[i] = new Intent(intent);
7597                 }
7598             }
7599             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7600                 throw new IllegalArgumentException(
7601                         "Intent array length does not match resolvedTypes length");
7602             }
7603         }
7604         if (bOptions != null) {
7605             if (bOptions.hasFileDescriptors()) {
7606                 throw new IllegalArgumentException("File descriptors passed in options");
7607             }
7608         }
7609
7610         synchronized(this) {
7611             int callingUid = Binder.getCallingUid();
7612             int origUserId = userId;
7613             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7614                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7615                     ALLOW_NON_FULL, "getIntentSender", null);
7616             if (origUserId == UserHandle.USER_CURRENT) {
7617                 // We don't want to evaluate this until the pending intent is
7618                 // actually executed.  However, we do want to always do the
7619                 // security checking for it above.
7620                 userId = UserHandle.USER_CURRENT;
7621             }
7622             try {
7623                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7624                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7625                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7626                     if (!UserHandle.isSameApp(callingUid, uid)) {
7627                         String msg = "Permission Denial: getIntentSender() from pid="
7628                             + Binder.getCallingPid()
7629                             + ", uid=" + Binder.getCallingUid()
7630                             + ", (need uid=" + uid + ")"
7631                             + " is not allowed to send as package " + packageName;
7632                         Slog.w(TAG, msg);
7633                         throw new SecurityException(msg);
7634                     }
7635                 }
7636
7637                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7638                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7639
7640             } catch (RemoteException e) {
7641                 throw new SecurityException(e);
7642             }
7643         }
7644     }
7645
7646     IIntentSender getIntentSenderLocked(int type, String packageName,
7647             int callingUid, int userId, IBinder token, String resultWho,
7648             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7649             Bundle bOptions) {
7650         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7651         ActivityRecord activity = null;
7652         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7653             activity = ActivityRecord.isInStackLocked(token);
7654             if (activity == null) {
7655                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7656                 return null;
7657             }
7658             if (activity.finishing) {
7659                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7660                 return null;
7661             }
7662         }
7663
7664         // We're going to be splicing together extras before sending, so we're
7665         // okay poking into any contained extras.
7666         if (intents != null) {
7667             for (int i = 0; i < intents.length; i++) {
7668                 intents[i].setDefusable(true);
7669             }
7670         }
7671         Bundle.setDefusable(bOptions, true);
7672
7673         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7674         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7675         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7676         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7677                 |PendingIntent.FLAG_UPDATE_CURRENT);
7678
7679         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7680                 type, packageName, activity, resultWho,
7681                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7682         WeakReference<PendingIntentRecord> ref;
7683         ref = mIntentSenderRecords.get(key);
7684         PendingIntentRecord rec = ref != null ? ref.get() : null;
7685         if (rec != null) {
7686             if (!cancelCurrent) {
7687                 if (updateCurrent) {
7688                     if (rec.key.requestIntent != null) {
7689                         rec.key.requestIntent.replaceExtras(intents != null ?
7690                                 intents[intents.length - 1] : null);
7691                     }
7692                     if (intents != null) {
7693                         intents[intents.length-1] = rec.key.requestIntent;
7694                         rec.key.allIntents = intents;
7695                         rec.key.allResolvedTypes = resolvedTypes;
7696                     } else {
7697                         rec.key.allIntents = null;
7698                         rec.key.allResolvedTypes = null;
7699                     }
7700                 }
7701                 return rec;
7702             }
7703             makeIntentSenderCanceledLocked(rec);
7704             mIntentSenderRecords.remove(key);
7705         }
7706         if (noCreate) {
7707             return rec;
7708         }
7709         rec = new PendingIntentRecord(this, key, callingUid);
7710         mIntentSenderRecords.put(key, rec.ref);
7711         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7712             if (activity.pendingResults == null) {
7713                 activity.pendingResults
7714                         = new HashSet<WeakReference<PendingIntentRecord>>();
7715             }
7716             activity.pendingResults.add(rec.ref);
7717         }
7718         return rec;
7719     }
7720
7721     @Override
7722     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7723             Intent intent, String resolvedType,
7724             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7725         if (target instanceof PendingIntentRecord) {
7726             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7727                     whitelistToken, finishedReceiver, requiredPermission, options);
7728         } else {
7729             if (intent == null) {
7730                 // Weird case: someone has given us their own custom IIntentSender, and now
7731                 // they have someone else trying to send to it but of course this isn't
7732                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7733                 // supplying an Intent... but we never want to dispatch a null Intent to
7734                 // a receiver, so um...  let's make something up.
7735                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7736                 intent = new Intent(Intent.ACTION_MAIN);
7737             }
7738             try {
7739                 target.send(code, intent, resolvedType, whitelistToken, null,
7740                         requiredPermission, options);
7741             } catch (RemoteException e) {
7742             }
7743             // Platform code can rely on getting a result back when the send is done, but if
7744             // this intent sender is from outside of the system we can't rely on it doing that.
7745             // So instead we don't give it the result receiver, and instead just directly
7746             // report the finish immediately.
7747             if (finishedReceiver != null) {
7748                 try {
7749                     finishedReceiver.performReceive(intent, 0,
7750                             null, null, false, false, UserHandle.getCallingUserId());
7751                 } catch (RemoteException e) {
7752                 }
7753             }
7754             return 0;
7755         }
7756     }
7757
7758     @Override
7759     public void cancelIntentSender(IIntentSender sender) {
7760         if (!(sender instanceof PendingIntentRecord)) {
7761             return;
7762         }
7763         synchronized(this) {
7764             PendingIntentRecord rec = (PendingIntentRecord)sender;
7765             try {
7766                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7767                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7768                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7769                     String msg = "Permission Denial: cancelIntentSender() from pid="
7770                         + Binder.getCallingPid()
7771                         + ", uid=" + Binder.getCallingUid()
7772                         + " is not allowed to cancel package "
7773                         + rec.key.packageName;
7774                     Slog.w(TAG, msg);
7775                     throw new SecurityException(msg);
7776                 }
7777             } catch (RemoteException e) {
7778                 throw new SecurityException(e);
7779             }
7780             cancelIntentSenderLocked(rec, true);
7781         }
7782     }
7783
7784     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7785         makeIntentSenderCanceledLocked(rec);
7786         mIntentSenderRecords.remove(rec.key);
7787         if (cleanActivity && rec.key.activity != null) {
7788             rec.key.activity.pendingResults.remove(rec.ref);
7789         }
7790     }
7791
7792     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7793         rec.canceled = true;
7794         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7795         if (callbacks != null) {
7796             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7797         }
7798     }
7799
7800     @Override
7801     public String getPackageForIntentSender(IIntentSender pendingResult) {
7802         if (!(pendingResult instanceof PendingIntentRecord)) {
7803             return null;
7804         }
7805         try {
7806             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7807             return res.key.packageName;
7808         } catch (ClassCastException e) {
7809         }
7810         return null;
7811     }
7812
7813     @Override
7814     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7815         if (!(sender instanceof PendingIntentRecord)) {
7816             return;
7817         }
7818         synchronized(this) {
7819             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7820         }
7821     }
7822
7823     @Override
7824     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7825             IResultReceiver receiver) {
7826         if (!(sender instanceof PendingIntentRecord)) {
7827             return;
7828         }
7829         synchronized(this) {
7830             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7831         }
7832     }
7833
7834     @Override
7835     public int getUidForIntentSender(IIntentSender sender) {
7836         if (sender instanceof PendingIntentRecord) {
7837             try {
7838                 PendingIntentRecord res = (PendingIntentRecord)sender;
7839                 return res.uid;
7840             } catch (ClassCastException e) {
7841             }
7842         }
7843         return -1;
7844     }
7845
7846     @Override
7847     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7848         if (!(pendingResult instanceof PendingIntentRecord)) {
7849             return false;
7850         }
7851         try {
7852             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7853             if (res.key.allIntents == null) {
7854                 return false;
7855             }
7856             for (int i=0; i<res.key.allIntents.length; i++) {
7857                 Intent intent = res.key.allIntents[i];
7858                 if (intent.getPackage() != null && intent.getComponent() != null) {
7859                     return false;
7860                 }
7861             }
7862             return true;
7863         } catch (ClassCastException e) {
7864         }
7865         return false;
7866     }
7867
7868     @Override
7869     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7870         if (!(pendingResult instanceof PendingIntentRecord)) {
7871             return false;
7872         }
7873         try {
7874             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7875             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7876                 return true;
7877             }
7878             return false;
7879         } catch (ClassCastException e) {
7880         }
7881         return false;
7882     }
7883
7884     @Override
7885     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7886         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7887                 "getIntentForIntentSender()");
7888         if (!(pendingResult instanceof PendingIntentRecord)) {
7889             return null;
7890         }
7891         try {
7892             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7893             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7894         } catch (ClassCastException e) {
7895         }
7896         return null;
7897     }
7898
7899     @Override
7900     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7901         if (!(pendingResult instanceof PendingIntentRecord)) {
7902             return null;
7903         }
7904         try {
7905             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7906             synchronized (this) {
7907                 return getTagForIntentSenderLocked(res, prefix);
7908             }
7909         } catch (ClassCastException e) {
7910         }
7911         return null;
7912     }
7913
7914     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7915         final Intent intent = res.key.requestIntent;
7916         if (intent != null) {
7917             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7918                     || res.lastTagPrefix.equals(prefix))) {
7919                 return res.lastTag;
7920             }
7921             res.lastTagPrefix = prefix;
7922             final StringBuilder sb = new StringBuilder(128);
7923             if (prefix != null) {
7924                 sb.append(prefix);
7925             }
7926             if (intent.getAction() != null) {
7927                 sb.append(intent.getAction());
7928             } else if (intent.getComponent() != null) {
7929                 intent.getComponent().appendShortString(sb);
7930             } else {
7931                 sb.append("?");
7932             }
7933             return res.lastTag = sb.toString();
7934         }
7935         return null;
7936     }
7937
7938     @Override
7939     public void setProcessLimit(int max) {
7940         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7941                 "setProcessLimit()");
7942         synchronized (this) {
7943             mConstants.setOverrideMaxCachedProcesses(max);
7944         }
7945         trimApplications();
7946     }
7947
7948     @Override
7949     public int getProcessLimit() {
7950         synchronized (this) {
7951             return mConstants.getOverrideMaxCachedProcesses();
7952         }
7953     }
7954
7955     void importanceTokenDied(ImportanceToken token) {
7956         synchronized (ActivityManagerService.this) {
7957             synchronized (mPidsSelfLocked) {
7958                 ImportanceToken cur
7959                     = mImportantProcesses.get(token.pid);
7960                 if (cur != token) {
7961                     return;
7962                 }
7963                 mImportantProcesses.remove(token.pid);
7964                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7965                 if (pr == null) {
7966                     return;
7967                 }
7968                 pr.forcingToImportant = null;
7969                 updateProcessForegroundLocked(pr, false, false);
7970             }
7971             updateOomAdjLocked();
7972         }
7973     }
7974
7975     @Override
7976     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7977         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7978                 "setProcessImportant()");
7979         synchronized(this) {
7980             boolean changed = false;
7981
7982             synchronized (mPidsSelfLocked) {
7983                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7984                 if (pr == null && isForeground) {
7985                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7986                     return;
7987                 }
7988                 ImportanceToken oldToken = mImportantProcesses.get(pid);
7989                 if (oldToken != null) {
7990                     oldToken.token.unlinkToDeath(oldToken, 0);
7991                     mImportantProcesses.remove(pid);
7992                     if (pr != null) {
7993                         pr.forcingToImportant = null;
7994                     }
7995                     changed = true;
7996                 }
7997                 if (isForeground && token != null) {
7998                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
7999                         @Override
8000                         public void binderDied() {
8001                             importanceTokenDied(this);
8002                         }
8003                     };
8004                     try {
8005                         token.linkToDeath(newToken, 0);
8006                         mImportantProcesses.put(pid, newToken);
8007                         pr.forcingToImportant = newToken;
8008                         changed = true;
8009                     } catch (RemoteException e) {
8010                         // If the process died while doing this, we will later
8011                         // do the cleanup with the process death link.
8012                     }
8013                 }
8014             }
8015
8016             if (changed) {
8017                 updateOomAdjLocked();
8018             }
8019         }
8020     }
8021
8022     @Override
8023     public boolean isAppForeground(int uid) throws RemoteException {
8024         int callerUid = Binder.getCallingUid();
8025         if (UserHandle.isCore(callerUid) || callerUid == uid) {
8026             return isAppForegroundInternal(uid);
8027         }
8028         return false;
8029     }
8030
8031     private boolean isAppForegroundInternal(int uid) {
8032         synchronized (this) {
8033             UidRecord uidRec = mActiveUids.get(uid);
8034             if (uidRec == null || uidRec.idle) {
8035                 return false;
8036             }
8037             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8038         }
8039     }
8040
8041     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8042     // be guarded by permission checking.
8043     int getUidState(int uid) {
8044         synchronized (this) {
8045             return getUidStateLocked(uid);
8046         }
8047     }
8048
8049     int getUidStateLocked(int uid) {
8050         UidRecord uidRec = mActiveUids.get(uid);
8051         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8052     }
8053
8054     @Override
8055     public boolean isInMultiWindowMode(IBinder token) {
8056         final long origId = Binder.clearCallingIdentity();
8057         try {
8058             synchronized(this) {
8059                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8060                 if (r == null) {
8061                     return false;
8062                 }
8063                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8064                 return !r.getTask().mFullscreen;
8065             }
8066         } finally {
8067             Binder.restoreCallingIdentity(origId);
8068         }
8069     }
8070
8071     @Override
8072     public boolean isInPictureInPictureMode(IBinder token) {
8073         final long origId = Binder.clearCallingIdentity();
8074         try {
8075             synchronized(this) {
8076                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8077             }
8078         } finally {
8079             Binder.restoreCallingIdentity(origId);
8080         }
8081     }
8082
8083     private boolean isInPictureInPictureMode(ActivityRecord r) {
8084         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8085                 r.getStack().isInStackLocked(r) == null) {
8086             return false;
8087         }
8088
8089         // If we are animating to fullscreen then we have already dispatched the PIP mode
8090         // changed, so we should reflect that check here as well.
8091         final PinnedActivityStack stack = r.getStack();
8092         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8093         return !windowController.isAnimatingBoundsToFullscreen();
8094     }
8095
8096     @Override
8097     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8098         final long origId = Binder.clearCallingIdentity();
8099         try {
8100             synchronized(this) {
8101                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8102                         "enterPictureInPictureMode", token, params);
8103
8104                 // If the activity is already in picture in picture mode, then just return early
8105                 if (isInPictureInPictureMode(r)) {
8106                     return true;
8107                 }
8108
8109                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8110                 // point, if it is
8111                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8112                         false /* beforeStopping */)) {
8113                     return false;
8114                 }
8115
8116                 final Runnable enterPipRunnable = () -> {
8117                     // Only update the saved args from the args that are set
8118                     r.pictureInPictureArgs.copyOnlySet(params);
8119                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8120                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8121                     // Adjust the source bounds by the insets for the transition down
8122                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8123                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8124                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8125                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8126                     stack.setPictureInPictureAspectRatio(aspectRatio);
8127                     stack.setPictureInPictureActions(actions);
8128
8129                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8130                             r.supportsEnterPipOnTaskSwitch);
8131                     logPictureInPictureArgs(params);
8132                 };
8133
8134                 if (isKeyguardLocked()) {
8135                     // If the keyguard is showing or occluded, then try and dismiss it before
8136                     // entering picture-in-picture (this will prompt the user to authenticate if the
8137                     // device is currently locked).
8138                     try {
8139                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8140                             @Override
8141                             public void onDismissError() throws RemoteException {
8142                                 // Do nothing
8143                             }
8144
8145                             @Override
8146                             public void onDismissSucceeded() throws RemoteException {
8147                                 mHandler.post(enterPipRunnable);
8148                             }
8149
8150                             @Override
8151                             public void onDismissCancelled() throws RemoteException {
8152                                 // Do nothing
8153                             }
8154                         });
8155                     } catch (RemoteException e) {
8156                         // Local call
8157                     }
8158                 } else {
8159                     // Enter picture in picture immediately otherwise
8160                     enterPipRunnable.run();
8161                 }
8162                 return true;
8163             }
8164         } finally {
8165             Binder.restoreCallingIdentity(origId);
8166         }
8167     }
8168
8169     @Override
8170     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8171         final long origId = Binder.clearCallingIdentity();
8172         try {
8173             synchronized(this) {
8174                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8175                         "setPictureInPictureParams", token, params);
8176
8177                 // Only update the saved args from the args that are set
8178                 r.pictureInPictureArgs.copyOnlySet(params);
8179                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8180                     // If the activity is already in picture-in-picture, update the pinned stack now
8181                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8182                     // be used the next time the activity enters PiP
8183                     final PinnedActivityStack stack = r.getStack();
8184                     if (!stack.isAnimatingBoundsToFullscreen()) {
8185                         stack.setPictureInPictureAspectRatio(
8186                                 r.pictureInPictureArgs.getAspectRatio());
8187                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8188                     }
8189                 }
8190                 logPictureInPictureArgs(params);
8191             }
8192         } finally {
8193             Binder.restoreCallingIdentity(origId);
8194         }
8195     }
8196
8197     @Override
8198     public int getMaxNumPictureInPictureActions(IBinder token) {
8199         // Currently, this is a static constant, but later, we may change this to be dependent on
8200         // the context of the activity
8201         return 3;
8202     }
8203
8204     private void logPictureInPictureArgs(PictureInPictureParams params) {
8205         if (params.hasSetActions()) {
8206             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8207                     params.getActions().size());
8208         }
8209         if (params.hasSetAspectRatio()) {
8210             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8211             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8212             MetricsLogger.action(lm);
8213         }
8214     }
8215
8216     /**
8217      * Checks the state of the system and the activity associated with the given {@param token} to
8218      * verify that picture-in-picture is supported for that activity.
8219      *
8220      * @return the activity record for the given {@param token} if all the checks pass.
8221      */
8222     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8223             IBinder token, PictureInPictureParams params) {
8224         if (!mSupportsPictureInPicture) {
8225             throw new IllegalStateException(caller
8226                     + ": Device doesn't support picture-in-picture mode.");
8227         }
8228
8229         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8230         if (r == null) {
8231             throw new IllegalStateException(caller
8232                     + ": Can't find activity for token=" + token);
8233         }
8234
8235         if (!r.supportsPictureInPicture()) {
8236             throw new IllegalStateException(caller
8237                     + ": Current activity does not support picture-in-picture.");
8238         }
8239
8240         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8241             throw new IllegalStateException(caller
8242                     + ": Activities on the home, assistant, or recents stack not supported");
8243         }
8244
8245         if (params.hasSetAspectRatio()
8246                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8247                         params.getAspectRatio())) {
8248             final float minAspectRatio = mContext.getResources().getFloat(
8249                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8250             final float maxAspectRatio = mContext.getResources().getFloat(
8251                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8252             throw new IllegalArgumentException(String.format(caller
8253                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8254                             minAspectRatio, maxAspectRatio));
8255         }
8256
8257         // Truncate the number of actions if necessary
8258         params.truncateActions(getMaxNumPictureInPictureActions(token));
8259
8260         return r;
8261     }
8262
8263     // =========================================================
8264     // PROCESS INFO
8265     // =========================================================
8266
8267     static class ProcessInfoService extends IProcessInfoService.Stub {
8268         final ActivityManagerService mActivityManagerService;
8269         ProcessInfoService(ActivityManagerService activityManagerService) {
8270             mActivityManagerService = activityManagerService;
8271         }
8272
8273         @Override
8274         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8275             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8276                     /*in*/ pids, /*out*/ states, null);
8277         }
8278
8279         @Override
8280         public void getProcessStatesAndOomScoresFromPids(
8281                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8282             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8283                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8284         }
8285     }
8286
8287     /**
8288      * For each PID in the given input array, write the current process state
8289      * for that process into the states array, or -1 to indicate that no
8290      * process with the given PID exists. If scores array is provided, write
8291      * the oom score for the process into the scores array, with INVALID_ADJ
8292      * indicating the PID doesn't exist.
8293      */
8294     public void getProcessStatesAndOomScoresForPIDs(
8295             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8296         if (scores != null) {
8297             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8298                     "getProcessStatesAndOomScoresForPIDs()");
8299         }
8300
8301         if (pids == null) {
8302             throw new NullPointerException("pids");
8303         } else if (states == null) {
8304             throw new NullPointerException("states");
8305         } else if (pids.length != states.length) {
8306             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8307         } else if (scores != null && pids.length != scores.length) {
8308             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8309         }
8310
8311         synchronized (mPidsSelfLocked) {
8312             for (int i = 0; i < pids.length; i++) {
8313                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8314                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8315                         pr.curProcState;
8316                 if (scores != null) {
8317                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8318                 }
8319             }
8320         }
8321     }
8322
8323     // =========================================================
8324     // PERMISSIONS
8325     // =========================================================
8326
8327     static class PermissionController extends IPermissionController.Stub {
8328         ActivityManagerService mActivityManagerService;
8329         PermissionController(ActivityManagerService activityManagerService) {
8330             mActivityManagerService = activityManagerService;
8331         }
8332
8333         @Override
8334         public boolean checkPermission(String permission, int pid, int uid) {
8335             return mActivityManagerService.checkPermission(permission, pid,
8336                     uid) == PackageManager.PERMISSION_GRANTED;
8337         }
8338
8339         @Override
8340         public String[] getPackagesForUid(int uid) {
8341             return mActivityManagerService.mContext.getPackageManager()
8342                     .getPackagesForUid(uid);
8343         }
8344
8345         @Override
8346         public boolean isRuntimePermission(String permission) {
8347             try {
8348                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8349                         .getPermissionInfo(permission, 0);
8350                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8351                         == PermissionInfo.PROTECTION_DANGEROUS;
8352             } catch (NameNotFoundException nnfe) {
8353                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8354             }
8355             return false;
8356         }
8357     }
8358
8359     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8360         @Override
8361         public int checkComponentPermission(String permission, int pid, int uid,
8362                 int owningUid, boolean exported) {
8363             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8364                     owningUid, exported);
8365         }
8366
8367         @Override
8368         public Object getAMSLock() {
8369             return ActivityManagerService.this;
8370         }
8371     }
8372
8373     /**
8374      * This can be called with or without the global lock held.
8375      */
8376     int checkComponentPermission(String permission, int pid, int uid,
8377             int owningUid, boolean exported) {
8378         if (pid == MY_PID) {
8379             return PackageManager.PERMISSION_GRANTED;
8380         }
8381         return ActivityManager.checkComponentPermission(permission, uid,
8382                 owningUid, exported);
8383     }
8384
8385     /**
8386      * As the only public entry point for permissions checking, this method
8387      * can enforce the semantic that requesting a check on a null global
8388      * permission is automatically denied.  (Internally a null permission
8389      * string is used when calling {@link #checkComponentPermission} in cases
8390      * when only uid-based security is needed.)
8391      *
8392      * This can be called with or without the global lock held.
8393      */
8394     @Override
8395     public int checkPermission(String permission, int pid, int uid) {
8396         if (permission == null) {
8397             return PackageManager.PERMISSION_DENIED;
8398         }
8399         return checkComponentPermission(permission, pid, uid, -1, true);
8400     }
8401
8402     @Override
8403     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8404         if (permission == null) {
8405             return PackageManager.PERMISSION_DENIED;
8406         }
8407
8408         // We might be performing an operation on behalf of an indirect binder
8409         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8410         // client identity accordingly before proceeding.
8411         Identity tlsIdentity = sCallerIdentity.get();
8412         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8413             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8414                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8415             uid = tlsIdentity.uid;
8416             pid = tlsIdentity.pid;
8417         }
8418
8419         return checkComponentPermission(permission, pid, uid, -1, true);
8420     }
8421
8422     /**
8423      * Binder IPC calls go through the public entry point.
8424      * This can be called with or without the global lock held.
8425      */
8426     int checkCallingPermission(String permission) {
8427         return checkPermission(permission,
8428                 Binder.getCallingPid(),
8429                 UserHandle.getAppId(Binder.getCallingUid()));
8430     }
8431
8432     /**
8433      * This can be called with or without the global lock held.
8434      */
8435     void enforceCallingPermission(String permission, String func) {
8436         if (checkCallingPermission(permission)
8437                 == PackageManager.PERMISSION_GRANTED) {
8438             return;
8439         }
8440
8441         String msg = "Permission Denial: " + func + " from pid="
8442                 + Binder.getCallingPid()
8443                 + ", uid=" + Binder.getCallingUid()
8444                 + " requires " + permission;
8445         Slog.w(TAG, msg);
8446         throw new SecurityException(msg);
8447     }
8448
8449     /**
8450      * Determine if UID is holding permissions required to access {@link Uri} in
8451      * the given {@link ProviderInfo}. Final permission checking is always done
8452      * in {@link ContentProvider}.
8453      */
8454     private final boolean checkHoldingPermissionsLocked(
8455             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8456         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8457                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8458         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8459             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8460                     != PERMISSION_GRANTED) {
8461                 return false;
8462             }
8463         }
8464         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8465     }
8466
8467     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8468             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8469         if (pi.applicationInfo.uid == uid) {
8470             return true;
8471         } else if (!pi.exported) {
8472             return false;
8473         }
8474
8475         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8476         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8477         try {
8478             // check if target holds top-level <provider> permissions
8479             if (!readMet && pi.readPermission != null && considerUidPermissions
8480                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8481                 readMet = true;
8482             }
8483             if (!writeMet && pi.writePermission != null && considerUidPermissions
8484                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8485                 writeMet = true;
8486             }
8487
8488             // track if unprotected read/write is allowed; any denied
8489             // <path-permission> below removes this ability
8490             boolean allowDefaultRead = pi.readPermission == null;
8491             boolean allowDefaultWrite = pi.writePermission == null;
8492
8493             // check if target holds any <path-permission> that match uri
8494             final PathPermission[] pps = pi.pathPermissions;
8495             if (pps != null) {
8496                 final String path = grantUri.uri.getPath();
8497                 int i = pps.length;
8498                 while (i > 0 && (!readMet || !writeMet)) {
8499                     i--;
8500                     PathPermission pp = pps[i];
8501                     if (pp.match(path)) {
8502                         if (!readMet) {
8503                             final String pprperm = pp.getReadPermission();
8504                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8505                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8506                                     + ": match=" + pp.match(path)
8507                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8508                             if (pprperm != null) {
8509                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8510                                         == PERMISSION_GRANTED) {
8511                                     readMet = true;
8512                                 } else {
8513                                     allowDefaultRead = false;
8514                                 }
8515                             }
8516                         }
8517                         if (!writeMet) {
8518                             final String ppwperm = pp.getWritePermission();
8519                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8520                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8521                                     + ": match=" + pp.match(path)
8522                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8523                             if (ppwperm != null) {
8524                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8525                                         == PERMISSION_GRANTED) {
8526                                     writeMet = true;
8527                                 } else {
8528                                     allowDefaultWrite = false;
8529                                 }
8530                             }
8531                         }
8532                     }
8533                 }
8534             }
8535
8536             // grant unprotected <provider> read/write, if not blocked by
8537             // <path-permission> above
8538             if (allowDefaultRead) readMet = true;
8539             if (allowDefaultWrite) writeMet = true;
8540
8541         } catch (RemoteException e) {
8542             return false;
8543         }
8544
8545         return readMet && writeMet;
8546     }
8547
8548     public boolean isAppStartModeDisabled(int uid, String packageName) {
8549         synchronized (this) {
8550             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8551                     == ActivityManager.APP_START_MODE_DISABLED;
8552         }
8553     }
8554
8555     // Unified app-op and target sdk check
8556     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8557         // Apps that target O+ are always subject to background check
8558         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8559             if (DEBUG_BACKGROUND_CHECK) {
8560                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8561             }
8562             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8563         }
8564         // ...and legacy apps get an AppOp check
8565         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8566                 uid, packageName);
8567         if (DEBUG_BACKGROUND_CHECK) {
8568             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8569         }
8570         switch (appop) {
8571             case AppOpsManager.MODE_ALLOWED:
8572                 return ActivityManager.APP_START_MODE_NORMAL;
8573             case AppOpsManager.MODE_IGNORED:
8574                 return ActivityManager.APP_START_MODE_DELAYED;
8575             default:
8576                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8577         }
8578     }
8579
8580     // Service launch is available to apps with run-in-background exemptions but
8581     // some other background operations are not.  If we're doing a check
8582     // of service-launch policy, allow those callers to proceed unrestricted.
8583     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8584         // Persistent app?
8585         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8586             if (DEBUG_BACKGROUND_CHECK) {
8587                 Slog.i(TAG, "App " + uid + "/" + packageName
8588                         + " is persistent; not restricted in background");
8589             }
8590             return ActivityManager.APP_START_MODE_NORMAL;
8591         }
8592
8593         // Non-persistent but background whitelisted?
8594         if (uidOnBackgroundWhitelist(uid)) {
8595             if (DEBUG_BACKGROUND_CHECK) {
8596                 Slog.i(TAG, "App " + uid + "/" + packageName
8597                         + " on background whitelist; not restricted in background");
8598             }
8599             return ActivityManager.APP_START_MODE_NORMAL;
8600         }
8601
8602         // Is this app on the battery whitelist?
8603         if (isOnDeviceIdleWhitelistLocked(uid)) {
8604             if (DEBUG_BACKGROUND_CHECK) {
8605                 Slog.i(TAG, "App " + uid + "/" + packageName
8606                         + " on idle whitelist; not restricted in background");
8607             }
8608             return ActivityManager.APP_START_MODE_NORMAL;
8609         }
8610
8611         // None of the service-policy criteria apply, so we apply the common criteria
8612         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8613     }
8614
8615     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8616             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8617         UidRecord uidRec = mActiveUids.get(uid);
8618         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8619                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8620                 + (uidRec != null ? uidRec.idle : false));
8621         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8622             boolean ephemeral;
8623             if (uidRec == null) {
8624                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8625                         UserHandle.getUserId(uid), packageName);
8626             } else {
8627                 ephemeral = uidRec.ephemeral;
8628             }
8629
8630             if (ephemeral) {
8631                 // We are hard-core about ephemeral apps not running in the background.
8632                 return ActivityManager.APP_START_MODE_DISABLED;
8633             } else {
8634                 if (disabledOnly) {
8635                     // The caller is only interested in whether app starts are completely
8636                     // disabled for the given package (that is, it is an instant app).  So
8637                     // we don't need to go further, which is all just seeing if we should
8638                     // apply a "delayed" mode for a regular app.
8639                     return ActivityManager.APP_START_MODE_NORMAL;
8640                 }
8641                 final int startMode = (alwaysRestrict)
8642                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8643                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8644                                 packageTargetSdk);
8645                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8646                         + " pkg=" + packageName + " startMode=" + startMode
8647                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8648                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8649                     // This is an old app that has been forced into a "compatible as possible"
8650                     // mode of background check.  To increase compatibility, we will allow other
8651                     // foreground apps to cause its services to start.
8652                     if (callingPid >= 0) {
8653                         ProcessRecord proc;
8654                         synchronized (mPidsSelfLocked) {
8655                             proc = mPidsSelfLocked.get(callingPid);
8656                         }
8657                         if (proc != null &&
8658                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8659                             // Whoever is instigating this is in the foreground, so we will allow it
8660                             // to go through.
8661                             return ActivityManager.APP_START_MODE_NORMAL;
8662                         }
8663                     }
8664                 }
8665                 return startMode;
8666             }
8667         }
8668         return ActivityManager.APP_START_MODE_NORMAL;
8669     }
8670
8671     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8672         final int appId = UserHandle.getAppId(uid);
8673         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8674                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8675                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8676     }
8677
8678     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8679         ProviderInfo pi = null;
8680         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8681         if (cpr != null) {
8682             pi = cpr.info;
8683         } else {
8684             try {
8685                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8686                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8687                         userHandle);
8688             } catch (RemoteException ex) {
8689             }
8690         }
8691         return pi;
8692     }
8693
8694     void grantEphemeralAccessLocked(int userId, Intent intent,
8695             int targetAppId, int ephemeralAppId) {
8696         getPackageManagerInternalLocked().
8697                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8698     }
8699
8700     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8701         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8702         if (targetUris != null) {
8703             return targetUris.get(grantUri);
8704         }
8705         return null;
8706     }
8707
8708     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8709             String targetPkg, int targetUid, GrantUri grantUri) {
8710         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8711         if (targetUris == null) {
8712             targetUris = Maps.newArrayMap();
8713             mGrantedUriPermissions.put(targetUid, targetUris);
8714         }
8715
8716         UriPermission perm = targetUris.get(grantUri);
8717         if (perm == null) {
8718             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8719             targetUris.put(grantUri, perm);
8720         }
8721
8722         return perm;
8723     }
8724
8725     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8726             final int modeFlags) {
8727         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8728         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8729                 : UriPermission.STRENGTH_OWNED;
8730
8731         // Root gets to do everything.
8732         if (uid == 0) {
8733             return true;
8734         }
8735
8736         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8737         if (perms == null) return false;
8738
8739         // First look for exact match
8740         final UriPermission exactPerm = perms.get(grantUri);
8741         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8742             return true;
8743         }
8744
8745         // No exact match, look for prefixes
8746         final int N = perms.size();
8747         for (int i = 0; i < N; i++) {
8748             final UriPermission perm = perms.valueAt(i);
8749             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8750                     && perm.getStrength(modeFlags) >= minStrength) {
8751                 return true;
8752             }
8753         }
8754
8755         return false;
8756     }
8757
8758     /**
8759      * @param uri This uri must NOT contain an embedded userId.
8760      * @param userId The userId in which the uri is to be resolved.
8761      */
8762     @Override
8763     public int checkUriPermission(Uri uri, int pid, int uid,
8764             final int modeFlags, int userId, IBinder callerToken) {
8765         enforceNotIsolatedCaller("checkUriPermission");
8766
8767         // Another redirected-binder-call permissions check as in
8768         // {@link checkPermissionWithToken}.
8769         Identity tlsIdentity = sCallerIdentity.get();
8770         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8771             uid = tlsIdentity.uid;
8772             pid = tlsIdentity.pid;
8773         }
8774
8775         // Our own process gets to do everything.
8776         if (pid == MY_PID) {
8777             return PackageManager.PERMISSION_GRANTED;
8778         }
8779         synchronized (this) {
8780             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8781                     ? PackageManager.PERMISSION_GRANTED
8782                     : PackageManager.PERMISSION_DENIED;
8783         }
8784     }
8785
8786     /**
8787      * Check if the targetPkg can be granted permission to access uri by
8788      * the callingUid using the given modeFlags.  Throws a security exception
8789      * if callingUid is not allowed to do this.  Returns the uid of the target
8790      * if the URI permission grant should be performed; returns -1 if it is not
8791      * needed (for example targetPkg already has permission to access the URI).
8792      * If you already know the uid of the target, you can supply it in
8793      * lastTargetUid else set that to -1.
8794      */
8795     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8796             final int modeFlags, int lastTargetUid) {
8797         if (!Intent.isAccessUriMode(modeFlags)) {
8798             return -1;
8799         }
8800
8801         if (targetPkg != null) {
8802             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8803                     "Checking grant " + targetPkg + " permission to " + grantUri);
8804         }
8805
8806         final IPackageManager pm = AppGlobals.getPackageManager();
8807
8808         // If this is not a content: uri, we can't do anything with it.
8809         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8810             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8811                     "Can't grant URI permission for non-content URI: " + grantUri);
8812             return -1;
8813         }
8814
8815         // Bail early if system is trying to hand out permissions directly; it
8816         // must always grant permissions on behalf of someone explicit.
8817         final int callingAppId = UserHandle.getAppId(callingUid);
8818         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8819             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8820                 // Exempted authority for cropping user photos in Settings app
8821             } else {
8822                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8823                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8824                 return -1;
8825             }
8826         }
8827
8828         final String authority = grantUri.uri.getAuthority();
8829         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8830                 MATCH_DEBUG_TRIAGED_MISSING);
8831         if (pi == null) {
8832             Slog.w(TAG, "No content provider found for permission check: " +
8833                     grantUri.uri.toSafeString());
8834             return -1;
8835         }
8836
8837         int targetUid = lastTargetUid;
8838         if (targetUid < 0 && targetPkg != null) {
8839             try {
8840                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8841                         UserHandle.getUserId(callingUid));
8842                 if (targetUid < 0) {
8843                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8844                             "Can't grant URI permission no uid for: " + targetPkg);
8845                     return -1;
8846                 }
8847             } catch (RemoteException ex) {
8848                 return -1;
8849             }
8850         }
8851
8852         // Figure out the value returned when access is allowed
8853         final int allowedResult;
8854         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8855             // If we're extending a persistable grant, then we need to return
8856             // "targetUid" so that we always create a grant data structure to
8857             // support take/release APIs
8858             allowedResult = targetUid;
8859         } else {
8860             // Otherwise, we can return "-1" to indicate that no grant data
8861             // structures need to be created
8862             allowedResult = -1;
8863         }
8864
8865         if (targetUid >= 0) {
8866             // First...  does the target actually need this permission?
8867             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8868                 // No need to grant the target this permission.
8869                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8870                         "Target " + targetPkg + " already has full permission to " + grantUri);
8871                 return allowedResult;
8872             }
8873         } else {
8874             // First...  there is no target package, so can anyone access it?
8875             boolean allowed = pi.exported;
8876             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8877                 if (pi.readPermission != null) {
8878                     allowed = false;
8879                 }
8880             }
8881             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8882                 if (pi.writePermission != null) {
8883                     allowed = false;
8884                 }
8885             }
8886             if (allowed) {
8887                 return allowedResult;
8888             }
8889         }
8890
8891         /* There is a special cross user grant if:
8892          * - The target is on another user.
8893          * - Apps on the current user can access the uri without any uid permissions.
8894          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8895          * grant uri permissions.
8896          */
8897         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8898                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8899                 modeFlags, false /*without considering the uid permissions*/);
8900
8901         // Second...  is the provider allowing granting of URI permissions?
8902         if (!specialCrossUserGrant) {
8903             if (!pi.grantUriPermissions) {
8904                 throw new SecurityException("Provider " + pi.packageName
8905                         + "/" + pi.name
8906                         + " does not allow granting of Uri permissions (uri "
8907                         + grantUri + ")");
8908             }
8909             if (pi.uriPermissionPatterns != null) {
8910                 final int N = pi.uriPermissionPatterns.length;
8911                 boolean allowed = false;
8912                 for (int i=0; i<N; i++) {
8913                     if (pi.uriPermissionPatterns[i] != null
8914                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8915                         allowed = true;
8916                         break;
8917                     }
8918                 }
8919                 if (!allowed) {
8920                     throw new SecurityException("Provider " + pi.packageName
8921                             + "/" + pi.name
8922                             + " does not allow granting of permission to path of Uri "
8923                             + grantUri);
8924                 }
8925             }
8926         }
8927
8928         // Third...  does the caller itself have permission to access
8929         // this uri?
8930         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8931             // Require they hold a strong enough Uri permission
8932             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8933                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8934                     throw new SecurityException(
8935                             "UID " + callingUid + " does not have permission to " + grantUri
8936                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8937                                     + "or related APIs");
8938                 } else {
8939                     throw new SecurityException(
8940                             "UID " + callingUid + " does not have permission to " + grantUri);
8941                 }
8942             }
8943         }
8944         return targetUid;
8945     }
8946
8947     /**
8948      * @param uri This uri must NOT contain an embedded userId.
8949      * @param userId The userId in which the uri is to be resolved.
8950      */
8951     @Override
8952     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8953             final int modeFlags, int userId) {
8954         enforceNotIsolatedCaller("checkGrantUriPermission");
8955         synchronized(this) {
8956             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8957                     new GrantUri(userId, uri, false), modeFlags, -1);
8958         }
8959     }
8960
8961     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8962             final int modeFlags, UriPermissionOwner owner) {
8963         if (!Intent.isAccessUriMode(modeFlags)) {
8964             return;
8965         }
8966
8967         // So here we are: the caller has the assumed permission
8968         // to the uri, and the target doesn't.  Let's now give this to
8969         // the target.
8970
8971         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8972                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8973
8974         final String authority = grantUri.uri.getAuthority();
8975         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8976                 MATCH_DEBUG_TRIAGED_MISSING);
8977         if (pi == null) {
8978             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8979             return;
8980         }
8981
8982         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8983             grantUri.prefix = true;
8984         }
8985         final UriPermission perm = findOrCreateUriPermissionLocked(
8986                 pi.packageName, targetPkg, targetUid, grantUri);
8987         perm.grantModes(modeFlags, owner);
8988     }
8989
8990     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8991             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8992         if (targetPkg == null) {
8993             throw new NullPointerException("targetPkg");
8994         }
8995         int targetUid;
8996         final IPackageManager pm = AppGlobals.getPackageManager();
8997         try {
8998             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8999         } catch (RemoteException ex) {
9000             return;
9001         }
9002
9003         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9004                 targetUid);
9005         if (targetUid < 0) {
9006             return;
9007         }
9008
9009         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9010                 owner);
9011     }
9012
9013     static class NeededUriGrants extends ArrayList<GrantUri> {
9014         final String targetPkg;
9015         final int targetUid;
9016         final int flags;
9017
9018         NeededUriGrants(String targetPkg, int targetUid, int flags) {
9019             this.targetPkg = targetPkg;
9020             this.targetUid = targetUid;
9021             this.flags = flags;
9022         }
9023     }
9024
9025     /**
9026      * Like checkGrantUriPermissionLocked, but takes an Intent.
9027      */
9028     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9029             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9030         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9031                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9032                 + " clip=" + (intent != null ? intent.getClipData() : null)
9033                 + " from " + intent + "; flags=0x"
9034                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9035
9036         if (targetPkg == null) {
9037             throw new NullPointerException("targetPkg");
9038         }
9039
9040         if (intent == null) {
9041             return null;
9042         }
9043         Uri data = intent.getData();
9044         ClipData clip = intent.getClipData();
9045         if (data == null && clip == null) {
9046             return null;
9047         }
9048         // Default userId for uris in the intent (if they don't specify it themselves)
9049         int contentUserHint = intent.getContentUserHint();
9050         if (contentUserHint == UserHandle.USER_CURRENT) {
9051             contentUserHint = UserHandle.getUserId(callingUid);
9052         }
9053         final IPackageManager pm = AppGlobals.getPackageManager();
9054         int targetUid;
9055         if (needed != null) {
9056             targetUid = needed.targetUid;
9057         } else {
9058             try {
9059                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9060                         targetUserId);
9061             } catch (RemoteException ex) {
9062                 return null;
9063             }
9064             if (targetUid < 0) {
9065                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9066                         "Can't grant URI permission no uid for: " + targetPkg
9067                         + " on user " + targetUserId);
9068                 return null;
9069             }
9070         }
9071         if (data != null) {
9072             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9073             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9074                     targetUid);
9075             if (targetUid > 0) {
9076                 if (needed == null) {
9077                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9078                 }
9079                 needed.add(grantUri);
9080             }
9081         }
9082         if (clip != null) {
9083             for (int i=0; i<clip.getItemCount(); i++) {
9084                 Uri uri = clip.getItemAt(i).getUri();
9085                 if (uri != null) {
9086                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9087                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9088                             targetUid);
9089                     if (targetUid > 0) {
9090                         if (needed == null) {
9091                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9092                         }
9093                         needed.add(grantUri);
9094                     }
9095                 } else {
9096                     Intent clipIntent = clip.getItemAt(i).getIntent();
9097                     if (clipIntent != null) {
9098                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9099                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9100                         if (newNeeded != null) {
9101                             needed = newNeeded;
9102                         }
9103                     }
9104                 }
9105             }
9106         }
9107
9108         return needed;
9109     }
9110
9111     /**
9112      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9113      */
9114     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9115             UriPermissionOwner owner) {
9116         if (needed != null) {
9117             for (int i=0; i<needed.size(); i++) {
9118                 GrantUri grantUri = needed.get(i);
9119                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9120                         grantUri, needed.flags, owner);
9121             }
9122         }
9123     }
9124
9125     void grantUriPermissionFromIntentLocked(int callingUid,
9126             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9127         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9128                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9129         if (needed == null) {
9130             return;
9131         }
9132
9133         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9134     }
9135
9136     /**
9137      * @param uri This uri must NOT contain an embedded userId.
9138      * @param userId The userId in which the uri is to be resolved.
9139      */
9140     @Override
9141     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9142             final int modeFlags, int userId) {
9143         enforceNotIsolatedCaller("grantUriPermission");
9144         GrantUri grantUri = new GrantUri(userId, uri, false);
9145         synchronized(this) {
9146             final ProcessRecord r = getRecordForAppLocked(caller);
9147             if (r == null) {
9148                 throw new SecurityException("Unable to find app for caller "
9149                         + caller
9150                         + " when granting permission to uri " + grantUri);
9151             }
9152             if (targetPkg == null) {
9153                 throw new IllegalArgumentException("null target");
9154             }
9155             if (grantUri == null) {
9156                 throw new IllegalArgumentException("null uri");
9157             }
9158
9159             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9160                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9161                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9162                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9163
9164             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9165                     UserHandle.getUserId(r.uid));
9166         }
9167     }
9168
9169     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9170         if (perm.modeFlags == 0) {
9171             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9172                     perm.targetUid);
9173             if (perms != null) {
9174                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9175                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9176
9177                 perms.remove(perm.uri);
9178                 if (perms.isEmpty()) {
9179                     mGrantedUriPermissions.remove(perm.targetUid);
9180                 }
9181             }
9182         }
9183     }
9184
9185     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9186             final int modeFlags) {
9187         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9188                 "Revoking all granted permissions to " + grantUri);
9189
9190         final IPackageManager pm = AppGlobals.getPackageManager();
9191         final String authority = grantUri.uri.getAuthority();
9192         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9193                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9194         if (pi == null) {
9195             Slog.w(TAG, "No content provider found for permission revoke: "
9196                     + grantUri.toSafeString());
9197             return;
9198         }
9199
9200         // Does the caller have this permission on the URI?
9201         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9202             // If they don't have direct access to the URI, then revoke any
9203             // ownerless URI permissions that have been granted to them.
9204             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9205             if (perms != null) {
9206                 boolean persistChanged = false;
9207                 for (int i = perms.size()-1; i >= 0; i--) {
9208                     final UriPermission perm = perms.valueAt(i);
9209                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9210                         continue;
9211                     }
9212                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9213                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9214                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9215                                 "Revoking non-owned " + perm.targetUid
9216                                 + " permission to " + perm.uri);
9217                         persistChanged |= perm.revokeModes(
9218                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9219                         if (perm.modeFlags == 0) {
9220                             perms.removeAt(i);
9221                         }
9222                     }
9223                 }
9224                 if (perms.isEmpty()) {
9225                     mGrantedUriPermissions.remove(callingUid);
9226                 }
9227                 if (persistChanged) {
9228                     schedulePersistUriGrants();
9229                 }
9230             }
9231             return;
9232         }
9233
9234         boolean persistChanged = false;
9235
9236         // Go through all of the permissions and remove any that match.
9237         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9238             final int targetUid = mGrantedUriPermissions.keyAt(i);
9239             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9240
9241             for (int j = perms.size()-1; j >= 0; j--) {
9242                 final UriPermission perm = perms.valueAt(j);
9243                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9244                     continue;
9245                 }
9246                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9247                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9248                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9249                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9250                     persistChanged |= perm.revokeModes(
9251                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9252                             targetPackage == null);
9253                     if (perm.modeFlags == 0) {
9254                         perms.removeAt(j);
9255                     }
9256                 }
9257             }
9258
9259             if (perms.isEmpty()) {
9260                 mGrantedUriPermissions.removeAt(i);
9261             }
9262         }
9263
9264         if (persistChanged) {
9265             schedulePersistUriGrants();
9266         }
9267     }
9268
9269     /**
9270      * @param uri This uri must NOT contain an embedded userId.
9271      * @param userId The userId in which the uri is to be resolved.
9272      */
9273     @Override
9274     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9275             final int modeFlags, int userId) {
9276         enforceNotIsolatedCaller("revokeUriPermission");
9277         synchronized(this) {
9278             final ProcessRecord r = getRecordForAppLocked(caller);
9279             if (r == null) {
9280                 throw new SecurityException("Unable to find app for caller "
9281                         + caller
9282                         + " when revoking permission to uri " + uri);
9283             }
9284             if (uri == null) {
9285                 Slog.w(TAG, "revokeUriPermission: null uri");
9286                 return;
9287             }
9288
9289             if (!Intent.isAccessUriMode(modeFlags)) {
9290                 return;
9291             }
9292
9293             final String authority = uri.getAuthority();
9294             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9295                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9296             if (pi == null) {
9297                 Slog.w(TAG, "No content provider found for permission revoke: "
9298                         + uri.toSafeString());
9299                 return;
9300             }
9301
9302             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9303                     modeFlags);
9304         }
9305     }
9306
9307     /**
9308      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9309      * given package.
9310      *
9311      * @param packageName Package name to match, or {@code null} to apply to all
9312      *            packages.
9313      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9314      *            to all users.
9315      * @param persistable If persistable grants should be removed.
9316      */
9317     private void removeUriPermissionsForPackageLocked(
9318             String packageName, int userHandle, boolean persistable) {
9319         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9320             throw new IllegalArgumentException("Must narrow by either package or user");
9321         }
9322
9323         boolean persistChanged = false;
9324
9325         int N = mGrantedUriPermissions.size();
9326         for (int i = 0; i < N; i++) {
9327             final int targetUid = mGrantedUriPermissions.keyAt(i);
9328             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9329
9330             // Only inspect grants matching user
9331             if (userHandle == UserHandle.USER_ALL
9332                     || userHandle == UserHandle.getUserId(targetUid)) {
9333                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9334                     final UriPermission perm = it.next();
9335
9336                     // Only inspect grants matching package
9337                     if (packageName == null || perm.sourcePkg.equals(packageName)
9338                             || perm.targetPkg.equals(packageName)) {
9339                         // Hacky solution as part of fixing a security bug; ignore
9340                         // grants associated with DownloadManager so we don't have
9341                         // to immediately launch it to regrant the permissions
9342                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9343                                 && !persistable) continue;
9344
9345                         persistChanged |= perm.revokeModes(persistable
9346                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9347
9348                         // Only remove when no modes remain; any persisted grants
9349                         // will keep this alive.
9350                         if (perm.modeFlags == 0) {
9351                             it.remove();
9352                         }
9353                     }
9354                 }
9355
9356                 if (perms.isEmpty()) {
9357                     mGrantedUriPermissions.remove(targetUid);
9358                     N--;
9359                     i--;
9360                 }
9361             }
9362         }
9363
9364         if (persistChanged) {
9365             schedulePersistUriGrants();
9366         }
9367     }
9368
9369     @Override
9370     public IBinder newUriPermissionOwner(String name) {
9371         enforceNotIsolatedCaller("newUriPermissionOwner");
9372         synchronized(this) {
9373             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9374             return owner.getExternalTokenLocked();
9375         }
9376     }
9377
9378     @Override
9379     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9380         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9381         synchronized(this) {
9382             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9383             if (r == null) {
9384                 throw new IllegalArgumentException("Activity does not exist; token="
9385                         + activityToken);
9386             }
9387             return r.getUriPermissionsLocked().getExternalTokenLocked();
9388         }
9389     }
9390     /**
9391      * @param uri This uri must NOT contain an embedded userId.
9392      * @param sourceUserId The userId in which the uri is to be resolved.
9393      * @param targetUserId The userId of the app that receives the grant.
9394      */
9395     @Override
9396     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9397             final int modeFlags, int sourceUserId, int targetUserId) {
9398         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9399                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9400                 "grantUriPermissionFromOwner", null);
9401         synchronized(this) {
9402             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9403             if (owner == null) {
9404                 throw new IllegalArgumentException("Unknown owner: " + token);
9405             }
9406             if (fromUid != Binder.getCallingUid()) {
9407                 if (Binder.getCallingUid() != myUid()) {
9408                     // Only system code can grant URI permissions on behalf
9409                     // of other users.
9410                     throw new SecurityException("nice try");
9411                 }
9412             }
9413             if (targetPkg == null) {
9414                 throw new IllegalArgumentException("null target");
9415             }
9416             if (uri == null) {
9417                 throw new IllegalArgumentException("null uri");
9418             }
9419
9420             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9421                     modeFlags, owner, targetUserId);
9422         }
9423     }
9424
9425     /**
9426      * @param uri This uri must NOT contain an embedded userId.
9427      * @param userId The userId in which the uri is to be resolved.
9428      */
9429     @Override
9430     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9431         synchronized(this) {
9432             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9433             if (owner == null) {
9434                 throw new IllegalArgumentException("Unknown owner: " + token);
9435             }
9436
9437             if (uri == null) {
9438                 owner.removeUriPermissionsLocked(mode);
9439             } else {
9440                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9441                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9442             }
9443         }
9444     }
9445
9446     private void schedulePersistUriGrants() {
9447         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9448             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9449                     10 * DateUtils.SECOND_IN_MILLIS);
9450         }
9451     }
9452
9453     private void writeGrantedUriPermissions() {
9454         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9455
9456         // Snapshot permissions so we can persist without lock
9457         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9458         synchronized (this) {
9459             final int size = mGrantedUriPermissions.size();
9460             for (int i = 0; i < size; i++) {
9461                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9462                 for (UriPermission perm : perms.values()) {
9463                     if (perm.persistedModeFlags != 0) {
9464                         persist.add(perm.snapshot());
9465                     }
9466                 }
9467             }
9468         }
9469
9470         FileOutputStream fos = null;
9471         try {
9472             fos = mGrantFile.startWrite();
9473
9474             XmlSerializer out = new FastXmlSerializer();
9475             out.setOutput(fos, StandardCharsets.UTF_8.name());
9476             out.startDocument(null, true);
9477             out.startTag(null, TAG_URI_GRANTS);
9478             for (UriPermission.Snapshot perm : persist) {
9479                 out.startTag(null, TAG_URI_GRANT);
9480                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9481                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9482                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9483                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9484                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9485                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9486                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9487                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9488                 out.endTag(null, TAG_URI_GRANT);
9489             }
9490             out.endTag(null, TAG_URI_GRANTS);
9491             out.endDocument();
9492
9493             mGrantFile.finishWrite(fos);
9494         } catch (IOException e) {
9495             if (fos != null) {
9496                 mGrantFile.failWrite(fos);
9497             }
9498         }
9499     }
9500
9501     private void readGrantedUriPermissionsLocked() {
9502         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9503
9504         final long now = System.currentTimeMillis();
9505
9506         FileInputStream fis = null;
9507         try {
9508             fis = mGrantFile.openRead();
9509             final XmlPullParser in = Xml.newPullParser();
9510             in.setInput(fis, StandardCharsets.UTF_8.name());
9511
9512             int type;
9513             while ((type = in.next()) != END_DOCUMENT) {
9514                 final String tag = in.getName();
9515                 if (type == START_TAG) {
9516                     if (TAG_URI_GRANT.equals(tag)) {
9517                         final int sourceUserId;
9518                         final int targetUserId;
9519                         final int userHandle = readIntAttribute(in,
9520                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9521                         if (userHandle != UserHandle.USER_NULL) {
9522                             // For backwards compatibility.
9523                             sourceUserId = userHandle;
9524                             targetUserId = userHandle;
9525                         } else {
9526                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9527                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9528                         }
9529                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9530                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9531                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9532                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9533                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9534                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9535
9536                         // Sanity check that provider still belongs to source package
9537                         // Both direct boot aware and unaware packages are fine as we
9538                         // will do filtering at query time to avoid multiple parsing.
9539                         final ProviderInfo pi = getProviderInfoLocked(
9540                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9541                                         | MATCH_DIRECT_BOOT_UNAWARE);
9542                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9543                             int targetUid = -1;
9544                             try {
9545                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9546                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9547                             } catch (RemoteException e) {
9548                             }
9549                             if (targetUid != -1) {
9550                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9551                                         sourcePkg, targetPkg, targetUid,
9552                                         new GrantUri(sourceUserId, uri, prefix));
9553                                 perm.initPersistedModes(modeFlags, createdTime);
9554                             }
9555                         } else {
9556                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9557                                     + " but instead found " + pi);
9558                         }
9559                     }
9560                 }
9561             }
9562         } catch (FileNotFoundException e) {
9563             // Missing grants is okay
9564         } catch (IOException e) {
9565             Slog.wtf(TAG, "Failed reading Uri grants", e);
9566         } catch (XmlPullParserException e) {
9567             Slog.wtf(TAG, "Failed reading Uri grants", e);
9568         } finally {
9569             IoUtils.closeQuietly(fis);
9570         }
9571     }
9572
9573     /**
9574      * @param uri This uri must NOT contain an embedded userId.
9575      * @param userId The userId in which the uri is to be resolved.
9576      */
9577     @Override
9578     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9579         enforceNotIsolatedCaller("takePersistableUriPermission");
9580
9581         Preconditions.checkFlagsArgument(modeFlags,
9582                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9583
9584         synchronized (this) {
9585             final int callingUid = Binder.getCallingUid();
9586             boolean persistChanged = false;
9587             GrantUri grantUri = new GrantUri(userId, uri, false);
9588
9589             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9590                     new GrantUri(userId, uri, false));
9591             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9592                     new GrantUri(userId, uri, true));
9593
9594             final boolean exactValid = (exactPerm != null)
9595                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9596             final boolean prefixValid = (prefixPerm != null)
9597                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9598
9599             if (!(exactValid || prefixValid)) {
9600                 throw new SecurityException("No persistable permission grants found for UID "
9601                         + callingUid + " and Uri " + grantUri.toSafeString());
9602             }
9603
9604             if (exactValid) {
9605                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9606             }
9607             if (prefixValid) {
9608                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9609             }
9610
9611             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9612
9613             if (persistChanged) {
9614                 schedulePersistUriGrants();
9615             }
9616         }
9617     }
9618
9619     /**
9620      * @param uri This uri must NOT contain an embedded userId.
9621      * @param userId The userId in which the uri is to be resolved.
9622      */
9623     @Override
9624     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9625         enforceNotIsolatedCaller("releasePersistableUriPermission");
9626
9627         Preconditions.checkFlagsArgument(modeFlags,
9628                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9629
9630         synchronized (this) {
9631             final int callingUid = Binder.getCallingUid();
9632             boolean persistChanged = false;
9633
9634             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9635                     new GrantUri(userId, uri, false));
9636             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9637                     new GrantUri(userId, uri, true));
9638             if (exactPerm == null && prefixPerm == null) {
9639                 throw new SecurityException("No permission grants found for UID " + callingUid
9640                         + " and Uri " + uri.toSafeString());
9641             }
9642
9643             if (exactPerm != null) {
9644                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9645                 removeUriPermissionIfNeededLocked(exactPerm);
9646             }
9647             if (prefixPerm != null) {
9648                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9649                 removeUriPermissionIfNeededLocked(prefixPerm);
9650             }
9651
9652             if (persistChanged) {
9653                 schedulePersistUriGrants();
9654             }
9655         }
9656     }
9657
9658     /**
9659      * Prune any older {@link UriPermission} for the given UID until outstanding
9660      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9661      *
9662      * @return if any mutations occured that require persisting.
9663      */
9664     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9665         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9666         if (perms == null) return false;
9667         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9668
9669         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9670         for (UriPermission perm : perms.values()) {
9671             if (perm.persistedModeFlags != 0) {
9672                 persisted.add(perm);
9673             }
9674         }
9675
9676         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9677         if (trimCount <= 0) return false;
9678
9679         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9680         for (int i = 0; i < trimCount; i++) {
9681             final UriPermission perm = persisted.get(i);
9682
9683             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9684                     "Trimming grant created at " + perm.persistedCreateTime);
9685
9686             perm.releasePersistableModes(~0);
9687             removeUriPermissionIfNeededLocked(perm);
9688         }
9689
9690         return true;
9691     }
9692
9693     @Override
9694     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9695             String packageName, boolean incoming) {
9696         enforceNotIsolatedCaller("getPersistedUriPermissions");
9697         Preconditions.checkNotNull(packageName, "packageName");
9698
9699         final int callingUid = Binder.getCallingUid();
9700         final int callingUserId = UserHandle.getUserId(callingUid);
9701         final IPackageManager pm = AppGlobals.getPackageManager();
9702         try {
9703             final int packageUid = pm.getPackageUid(packageName,
9704                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9705             if (packageUid != callingUid) {
9706                 throw new SecurityException(
9707                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9708             }
9709         } catch (RemoteException e) {
9710             throw new SecurityException("Failed to verify package name ownership");
9711         }
9712
9713         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9714         synchronized (this) {
9715             if (incoming) {
9716                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9717                         callingUid);
9718                 if (perms == null) {
9719                     Slog.w(TAG, "No permission grants found for " + packageName);
9720                 } else {
9721                     for (UriPermission perm : perms.values()) {
9722                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9723                             result.add(perm.buildPersistedPublicApiObject());
9724                         }
9725                     }
9726                 }
9727             } else {
9728                 final int size = mGrantedUriPermissions.size();
9729                 for (int i = 0; i < size; i++) {
9730                     final ArrayMap<GrantUri, UriPermission> perms =
9731                             mGrantedUriPermissions.valueAt(i);
9732                     for (UriPermission perm : perms.values()) {
9733                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9734                             result.add(perm.buildPersistedPublicApiObject());
9735                         }
9736                     }
9737                 }
9738             }
9739         }
9740         return new ParceledListSlice<android.content.UriPermission>(result);
9741     }
9742
9743     @Override
9744     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9745             String packageName, int userId) {
9746         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9747                 "getGrantedUriPermissions");
9748
9749         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9750         synchronized (this) {
9751             final int size = mGrantedUriPermissions.size();
9752             for (int i = 0; i < size; i++) {
9753                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9754                 for (UriPermission perm : perms.values()) {
9755                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9756                             && perm.persistedModeFlags != 0) {
9757                         result.add(perm.buildPersistedPublicApiObject());
9758                     }
9759                 }
9760             }
9761         }
9762         return new ParceledListSlice<android.content.UriPermission>(result);
9763     }
9764
9765     @Override
9766     public void clearGrantedUriPermissions(String packageName, int userId) {
9767         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9768                 "clearGrantedUriPermissions");
9769         removeUriPermissionsForPackageLocked(packageName, userId, true);
9770     }
9771
9772     @Override
9773     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9774         synchronized (this) {
9775             ProcessRecord app =
9776                 who != null ? getRecordForAppLocked(who) : null;
9777             if (app == null) return;
9778
9779             Message msg = Message.obtain();
9780             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9781             msg.obj = app;
9782             msg.arg1 = waiting ? 1 : 0;
9783             mUiHandler.sendMessage(msg);
9784         }
9785     }
9786
9787     @Override
9788     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9789         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9790         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9791         outInfo.availMem = getFreeMemory();
9792         outInfo.totalMem = getTotalMemory();
9793         outInfo.threshold = homeAppMem;
9794         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9795         outInfo.hiddenAppThreshold = cachedAppMem;
9796         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9797                 ProcessList.SERVICE_ADJ);
9798         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9799                 ProcessList.VISIBLE_APP_ADJ);
9800         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9801                 ProcessList.FOREGROUND_APP_ADJ);
9802     }
9803
9804     // =========================================================
9805     // TASK MANAGEMENT
9806     // =========================================================
9807
9808     @Override
9809     public List<IBinder> getAppTasks(String callingPackage) {
9810         int callingUid = Binder.getCallingUid();
9811         long ident = Binder.clearCallingIdentity();
9812
9813         synchronized(this) {
9814             ArrayList<IBinder> list = new ArrayList<IBinder>();
9815             try {
9816                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9817
9818                 final int N = mRecentTasks.size();
9819                 for (int i = 0; i < N; i++) {
9820                     TaskRecord tr = mRecentTasks.get(i);
9821                     // Skip tasks that do not match the caller.  We don't need to verify
9822                     // callingPackage, because we are also limiting to callingUid and know
9823                     // that will limit to the correct security sandbox.
9824                     if (tr.effectiveUid != callingUid) {
9825                         continue;
9826                     }
9827                     Intent intent = tr.getBaseIntent();
9828                     if (intent == null ||
9829                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9830                         continue;
9831                     }
9832                     ActivityManager.RecentTaskInfo taskInfo =
9833                             createRecentTaskInfoFromTaskRecord(tr);
9834                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9835                     list.add(taskImpl.asBinder());
9836                 }
9837             } finally {
9838                 Binder.restoreCallingIdentity(ident);
9839             }
9840             return list;
9841         }
9842     }
9843
9844     @Override
9845     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9846         final int callingUid = Binder.getCallingUid();
9847         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9848
9849         synchronized(this) {
9850             if (DEBUG_ALL) Slog.v(
9851                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9852
9853             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9854                     callingUid);
9855
9856             // TODO: Improve with MRU list from all ActivityStacks.
9857             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9858         }
9859
9860         return list;
9861     }
9862
9863     /**
9864      * Creates a new RecentTaskInfo from a TaskRecord.
9865      */
9866     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9867         // Update the task description to reflect any changes in the task stack
9868         tr.updateTaskDescription();
9869
9870         // Compose the recent task info
9871         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9872         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9873         rti.persistentId = tr.taskId;
9874         rti.baseIntent = new Intent(tr.getBaseIntent());
9875         rti.origActivity = tr.origActivity;
9876         rti.realActivity = tr.realActivity;
9877         rti.description = tr.lastDescription;
9878         rti.stackId = tr.getStackId();
9879         rti.userId = tr.userId;
9880         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9881         rti.firstActiveTime = tr.firstActiveTime;
9882         rti.lastActiveTime = tr.lastActiveTime;
9883         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9884         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9885         rti.numActivities = 0;
9886         if (tr.mBounds != null) {
9887             rti.bounds = new Rect(tr.mBounds);
9888         }
9889         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9890         rti.resizeMode = tr.mResizeMode;
9891
9892         ActivityRecord base = null;
9893         ActivityRecord top = null;
9894         ActivityRecord tmp;
9895
9896         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9897             tmp = tr.mActivities.get(i);
9898             if (tmp.finishing) {
9899                 continue;
9900             }
9901             base = tmp;
9902             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9903                 top = base;
9904             }
9905             rti.numActivities++;
9906         }
9907
9908         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9909         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9910
9911         return rti;
9912     }
9913
9914     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9915         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9916                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9917         if (!allowed) {
9918             if (checkPermission(android.Manifest.permission.GET_TASKS,
9919                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9920                 // Temporary compatibility: some existing apps on the system image may
9921                 // still be requesting the old permission and not switched to the new
9922                 // one; if so, we'll still allow them full access.  This means we need
9923                 // to see if they are holding the old permission and are a system app.
9924                 try {
9925                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9926                         allowed = true;
9927                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9928                                 + " is using old GET_TASKS but privileged; allowing");
9929                     }
9930                 } catch (RemoteException e) {
9931                 }
9932             }
9933         }
9934         if (!allowed) {
9935             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9936                     + " does not hold REAL_GET_TASKS; limiting output");
9937         }
9938         return allowed;
9939     }
9940
9941     @Override
9942     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9943             int userId) {
9944         final int callingUid = Binder.getCallingUid();
9945         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9946                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9947
9948         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9949         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9950         synchronized (this) {
9951             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9952                     callingUid);
9953             final boolean detailed = checkCallingPermission(
9954                     android.Manifest.permission.GET_DETAILED_TASKS)
9955                     == PackageManager.PERMISSION_GRANTED;
9956
9957             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9958                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9959                 return ParceledListSlice.emptyList();
9960             }
9961             mRecentTasks.loadUserRecentsLocked(userId);
9962
9963             final int recentsCount = mRecentTasks.size();
9964             ArrayList<ActivityManager.RecentTaskInfo> res =
9965                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9966
9967             final Set<Integer> includedUsers;
9968             if (includeProfiles) {
9969                 includedUsers = mUserController.getProfileIds(userId);
9970             } else {
9971                 includedUsers = new HashSet<>();
9972             }
9973             includedUsers.add(Integer.valueOf(userId));
9974
9975             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9976                 TaskRecord tr = mRecentTasks.get(i);
9977                 // Only add calling user or related users recent tasks
9978                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9979                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9980                     continue;
9981                 }
9982
9983                 if (tr.realActivitySuspended) {
9984                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9985                     continue;
9986                 }
9987
9988                 // Return the entry if desired by the caller.  We always return
9989                 // the first entry, because callers always expect this to be the
9990                 // foreground app.  We may filter others if the caller has
9991                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9992                 // we should exclude the entry.
9993
9994                 if (i == 0
9995                         || withExcluded
9996                         || (tr.intent == null)
9997                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9998                                 == 0)) {
9999                     if (!allowed) {
10000                         // If the caller doesn't have the GET_TASKS permission, then only
10001                         // allow them to see a small subset of tasks -- their own and home.
10002                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
10003                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10004                             continue;
10005                         }
10006                     }
10007                     final ActivityStack stack = tr.getStack();
10008                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10009                         if (stack != null && stack.isHomeOrRecentsStack()) {
10010                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10011                                     "Skipping, home or recents stack task: " + tr);
10012                             continue;
10013                         }
10014                     }
10015                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10016                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10017                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10018                                     "Skipping, top task in docked stack: " + tr);
10019                             continue;
10020                         }
10021                     }
10022                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10023                         if (stack != null && stack.isPinnedStack()) {
10024                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10025                                     "Skipping, pinned stack task: " + tr);
10026                             continue;
10027                         }
10028                     }
10029                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10030                         // Don't include auto remove tasks that are finished or finishing.
10031                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10032                                 "Skipping, auto-remove without activity: " + tr);
10033                         continue;
10034                     }
10035                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10036                             && !tr.isAvailable) {
10037                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10038                                 "Skipping, unavail real act: " + tr);
10039                         continue;
10040                     }
10041
10042                     if (!tr.mUserSetupComplete) {
10043                         // Don't include task launched while user is not done setting-up.
10044                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10045                                 "Skipping, user setup not complete: " + tr);
10046                         continue;
10047                     }
10048
10049                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10050                     if (!detailed) {
10051                         rti.baseIntent.replaceExtras((Bundle)null);
10052                     }
10053
10054                     res.add(rti);
10055                     maxNum--;
10056                 }
10057             }
10058             return new ParceledListSlice<>(res);
10059         }
10060     }
10061
10062     @Override
10063     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10064         synchronized (this) {
10065             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10066                     "getTaskThumbnail()");
10067             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10068                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10069             if (tr != null) {
10070                 return tr.getTaskThumbnailLocked();
10071             }
10072         }
10073         return null;
10074     }
10075
10076     @Override
10077     public ActivityManager.TaskDescription getTaskDescription(int id) {
10078         synchronized (this) {
10079             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10080                     "getTaskDescription()");
10081             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10082                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10083             if (tr != null) {
10084                 return tr.lastTaskDescription;
10085             }
10086         }
10087         return null;
10088     }
10089
10090     @Override
10091     public int addAppTask(IBinder activityToken, Intent intent,
10092             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10093         final int callingUid = Binder.getCallingUid();
10094         final long callingIdent = Binder.clearCallingIdentity();
10095
10096         try {
10097             synchronized (this) {
10098                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10099                 if (r == null) {
10100                     throw new IllegalArgumentException("Activity does not exist; token="
10101                             + activityToken);
10102                 }
10103                 ComponentName comp = intent.getComponent();
10104                 if (comp == null) {
10105                     throw new IllegalArgumentException("Intent " + intent
10106                             + " must specify explicit component");
10107                 }
10108                 if (thumbnail.getWidth() != mThumbnailWidth
10109                         || thumbnail.getHeight() != mThumbnailHeight) {
10110                     throw new IllegalArgumentException("Bad thumbnail size: got "
10111                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10112                             + mThumbnailWidth + "x" + mThumbnailHeight);
10113                 }
10114                 if (intent.getSelector() != null) {
10115                     intent.setSelector(null);
10116                 }
10117                 if (intent.getSourceBounds() != null) {
10118                     intent.setSourceBounds(null);
10119                 }
10120                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10121                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10122                         // The caller has added this as an auto-remove task...  that makes no
10123                         // sense, so turn off auto-remove.
10124                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10125                     }
10126                 }
10127                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10128                     mLastAddedTaskActivity = null;
10129                 }
10130                 ActivityInfo ainfo = mLastAddedTaskActivity;
10131                 if (ainfo == null) {
10132                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10133                             comp, 0, UserHandle.getUserId(callingUid));
10134                     if (ainfo.applicationInfo.uid != callingUid) {
10135                         throw new SecurityException(
10136                                 "Can't add task for another application: target uid="
10137                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10138                     }
10139                 }
10140
10141                 TaskRecord task = new TaskRecord(this,
10142                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10143                         ainfo, intent, description, new TaskThumbnailInfo());
10144
10145                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10146                 if (trimIdx >= 0) {
10147                     // If this would have caused a trim, then we'll abort because that
10148                     // means it would be added at the end of the list but then just removed.
10149                     return INVALID_TASK_ID;
10150                 }
10151
10152                 final int N = mRecentTasks.size();
10153                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10154                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10155                     tr.removedFromRecents();
10156                 }
10157
10158                 task.inRecents = true;
10159                 mRecentTasks.add(task);
10160                 r.getStack().addTask(task, false, "addAppTask");
10161
10162                 task.setLastThumbnailLocked(thumbnail);
10163                 task.freeLastThumbnail();
10164                 return task.taskId;
10165             }
10166         } finally {
10167             Binder.restoreCallingIdentity(callingIdent);
10168         }
10169     }
10170
10171     @Override
10172     public Point getAppTaskThumbnailSize() {
10173         synchronized (this) {
10174             return new Point(mThumbnailWidth,  mThumbnailHeight);
10175         }
10176     }
10177
10178     @Override
10179     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10180         synchronized (this) {
10181             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10182             if (r != null) {
10183                 r.setTaskDescription(td);
10184                 final TaskRecord task = r.getTask();
10185                 task.updateTaskDescription();
10186                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10187             }
10188         }
10189     }
10190
10191     @Override
10192     public void setTaskResizeable(int taskId, int resizeableMode) {
10193         synchronized (this) {
10194             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10195                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10196             if (task == null) {
10197                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10198                 return;
10199             }
10200             task.setResizeMode(resizeableMode);
10201         }
10202     }
10203
10204     @Override
10205     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10206         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10207         long ident = Binder.clearCallingIdentity();
10208         try {
10209             synchronized (this) {
10210                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10211                 if (task == null) {
10212                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10213                     return;
10214                 }
10215                 // Place the task in the right stack if it isn't there already based on
10216                 // the requested bounds.
10217                 // The stack transition logic is:
10218                 // - a null bounds on a freeform task moves that task to fullscreen
10219                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10220                 //   that task to freeform
10221                 // - otherwise the task is not moved
10222                 int stackId = task.getStackId();
10223                 if (!StackId.isTaskResizeAllowed(stackId)) {
10224                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10225                 }
10226                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10227                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10228                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10229                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10230                 }
10231
10232                 // Reparent the task to the right stack if necessary
10233                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10234                 if (stackId != task.getStackId()) {
10235                     // Defer resume until the task is resized below
10236                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10237                             DEFER_RESUME, "resizeTask");
10238                     preserveWindow = false;
10239                 }
10240
10241                 // After reparenting (which only resizes the task to the stack bounds), resize the
10242                 // task to the actual bounds provided
10243                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10244             }
10245         } finally {
10246             Binder.restoreCallingIdentity(ident);
10247         }
10248     }
10249
10250     @Override
10251     public Rect getTaskBounds(int taskId) {
10252         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10253         long ident = Binder.clearCallingIdentity();
10254         Rect rect = new Rect();
10255         try {
10256             synchronized (this) {
10257                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10258                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10259                 if (task == null) {
10260                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10261                     return rect;
10262                 }
10263                 if (task.getStack() != null) {
10264                     // Return the bounds from window manager since it will be adjusted for various
10265                     // things like the presense of a docked stack for tasks that aren't resizeable.
10266                     task.getWindowContainerBounds(rect);
10267                 } else {
10268                     // Task isn't in window manager yet since it isn't associated with a stack.
10269                     // Return the persist value from activity manager
10270                     if (task.mBounds != null) {
10271                         rect.set(task.mBounds);
10272                     } else if (task.mLastNonFullscreenBounds != null) {
10273                         rect.set(task.mLastNonFullscreenBounds);
10274                     }
10275                 }
10276             }
10277         } finally {
10278             Binder.restoreCallingIdentity(ident);
10279         }
10280         return rect;
10281     }
10282
10283     @Override
10284     public void cancelTaskWindowTransition(int taskId) {
10285         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10286         final long ident = Binder.clearCallingIdentity();
10287         try {
10288             synchronized (this) {
10289                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10290                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10291                 if (task == null) {
10292                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10293                     return;
10294                 }
10295                 task.cancelWindowTransition();
10296             }
10297         } finally {
10298             Binder.restoreCallingIdentity(ident);
10299         }
10300     }
10301
10302     @Override
10303     public void cancelTaskThumbnailTransition(int taskId) {
10304         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10305         final long ident = Binder.clearCallingIdentity();
10306         try {
10307             synchronized (this) {
10308                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10309                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10310                 if (task == null) {
10311                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10312                     return;
10313                 }
10314                 task.cancelThumbnailTransition();
10315             }
10316         } finally {
10317             Binder.restoreCallingIdentity(ident);
10318         }
10319     }
10320
10321     @Override
10322     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10323         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10324         final long ident = Binder.clearCallingIdentity();
10325         try {
10326             final TaskRecord task;
10327             synchronized (this) {
10328                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10329                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10330                 if (task == null) {
10331                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10332                     return null;
10333                 }
10334             }
10335             // Don't call this while holding the lock as this operation might hit the disk.
10336             return task.getSnapshot(reducedResolution);
10337         } finally {
10338             Binder.restoreCallingIdentity(ident);
10339         }
10340     }
10341
10342     @Override
10343     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10344         if (userId != UserHandle.getCallingUserId()) {
10345             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10346                     "getTaskDescriptionIcon");
10347         }
10348         final File passedIconFile = new File(filePath);
10349         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10350                 passedIconFile.getName());
10351         if (!legitIconFile.getPath().equals(filePath)
10352                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10353             throw new IllegalArgumentException("Bad file path: " + filePath
10354                     + " passed for userId " + userId);
10355         }
10356         return mRecentTasks.getTaskDescriptionIcon(filePath);
10357     }
10358
10359     @Override
10360     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10361             throws RemoteException {
10362         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10363         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10364                 activityOptions.getCustomInPlaceResId() == 0) {
10365             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10366                     "with valid animation");
10367         }
10368         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10369         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10370                 activityOptions.getCustomInPlaceResId());
10371         mWindowManager.executeAppTransition();
10372     }
10373
10374     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10375         // Remove all tasks with activities in the specified package from the list of recent tasks
10376         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10377             TaskRecord tr = mRecentTasks.get(i);
10378             if (tr.userId != userId) continue;
10379
10380             ComponentName cn = tr.intent.getComponent();
10381             if (cn != null && cn.getPackageName().equals(packageName)) {
10382                 // If the package name matches, remove the task.
10383                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10384             }
10385         }
10386     }
10387
10388     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10389             int userId) {
10390
10391         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10392             TaskRecord tr = mRecentTasks.get(i);
10393             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10394                 continue;
10395             }
10396
10397             ComponentName cn = tr.intent.getComponent();
10398             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10399                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10400             if (sameComponent) {
10401                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10402             }
10403         }
10404     }
10405
10406     @Override
10407     public void removeStack(int stackId) {
10408         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10409         if (StackId.isHomeOrRecentsStack(stackId)) {
10410             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10411         }
10412
10413         synchronized (this) {
10414             final long ident = Binder.clearCallingIdentity();
10415             try {
10416                 mStackSupervisor.removeStackLocked(stackId);
10417             } finally {
10418                 Binder.restoreCallingIdentity(ident);
10419             }
10420         }
10421     }
10422
10423     @Override
10424     public void moveStackToDisplay(int stackId, int displayId) {
10425         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10426
10427         synchronized (this) {
10428             final long ident = Binder.clearCallingIdentity();
10429             try {
10430                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10431                         + " to displayId=" + displayId);
10432                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10433             } finally {
10434                 Binder.restoreCallingIdentity(ident);
10435             }
10436         }
10437     }
10438
10439     @Override
10440     public boolean removeTask(int taskId) {
10441         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10442         synchronized (this) {
10443             final long ident = Binder.clearCallingIdentity();
10444             try {
10445                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10446             } finally {
10447                 Binder.restoreCallingIdentity(ident);
10448             }
10449         }
10450     }
10451
10452     /**
10453      * TODO: Add mController hook
10454      */
10455     @Override
10456     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10457         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10458
10459         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10460         synchronized(this) {
10461             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10462         }
10463     }
10464
10465     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10466         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10467
10468         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10469                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10470             ActivityOptions.abort(options);
10471             return;
10472         }
10473         final long origId = Binder.clearCallingIdentity();
10474         try {
10475             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10476             if (task == null) {
10477                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10478                 return;
10479             }
10480             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10481                 mStackSupervisor.showLockTaskToast();
10482                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10483                 return;
10484             }
10485             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10486             if (prev != null) {
10487                 task.setTaskToReturnTo(prev);
10488             }
10489             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10490                     false /* forceNonResizable */);
10491
10492             final ActivityRecord topActivity = task.getTopActivity();
10493             if (topActivity != null) {
10494
10495                 // We are reshowing a task, use a starting window to hide the initial draw delay
10496                 // so the transition can start earlier.
10497                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10498                         true /* taskSwitch */, fromRecents);
10499             }
10500         } finally {
10501             Binder.restoreCallingIdentity(origId);
10502         }
10503         ActivityOptions.abort(options);
10504     }
10505
10506     /**
10507      * Attempts to move a task backwards in z-order (the order of activities within the task is
10508      * unchanged).
10509      *
10510      * There are several possible results of this call:
10511      * - if the task is locked, then we will show the lock toast
10512      * - if there is a task behind the provided task, then that task is made visible and resumed as
10513      *   this task is moved to the back
10514      * - otherwise, if there are no other tasks in the stack:
10515      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10516      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10517      *       (depending on whether it is visible)
10518      *     - otherwise, we simply return home and hide this task
10519      *
10520      * @param token A reference to the activity we wish to move
10521      * @param nonRoot If false then this only works if the activity is the root
10522      *                of a task; if true it will work for any activity in a task.
10523      * @return Returns true if the move completed, false if not.
10524      */
10525     @Override
10526     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10527         enforceNotIsolatedCaller("moveActivityTaskToBack");
10528         synchronized(this) {
10529             final long origId = Binder.clearCallingIdentity();
10530             try {
10531                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10532                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10533                 if (task != null) {
10534                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10535                 }
10536             } finally {
10537                 Binder.restoreCallingIdentity(origId);
10538             }
10539         }
10540         return false;
10541     }
10542
10543     @Override
10544     public void moveTaskBackwards(int task) {
10545         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10546                 "moveTaskBackwards()");
10547
10548         synchronized(this) {
10549             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10550                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10551                 return;
10552             }
10553             final long origId = Binder.clearCallingIdentity();
10554             moveTaskBackwardsLocked(task);
10555             Binder.restoreCallingIdentity(origId);
10556         }
10557     }
10558
10559     private final void moveTaskBackwardsLocked(int task) {
10560         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10561     }
10562
10563     @Override
10564     public int createStackOnDisplay(int displayId) throws RemoteException {
10565         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10566         synchronized (this) {
10567             final int stackId = mStackSupervisor.getNextStackId();
10568             final ActivityStack stack =
10569                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10570             if (stack == null) {
10571                 return INVALID_STACK_ID;
10572             }
10573             return stack.mStackId;
10574         }
10575     }
10576
10577     @Override
10578     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10579         synchronized (this) {
10580             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10581             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10582                 return stack.mDisplayId;
10583             }
10584             return DEFAULT_DISPLAY;
10585         }
10586     }
10587
10588     @Override
10589     public int getActivityStackId(IBinder token) throws RemoteException {
10590         synchronized (this) {
10591             ActivityStack stack = ActivityRecord.getStackLocked(token);
10592             if (stack == null) {
10593                 return INVALID_STACK_ID;
10594             }
10595             return stack.mStackId;
10596         }
10597     }
10598
10599     @Override
10600     public void exitFreeformMode(IBinder token) throws RemoteException {
10601         synchronized (this) {
10602             long ident = Binder.clearCallingIdentity();
10603             try {
10604                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10605                 if (r == null) {
10606                     throw new IllegalArgumentException(
10607                             "exitFreeformMode: No activity record matching token=" + token);
10608                 }
10609
10610                 final ActivityStack stack = r.getStack();
10611                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10612                     throw new IllegalStateException(
10613                             "exitFreeformMode: You can only go fullscreen from freeform.");
10614                 }
10615
10616                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10617                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10618                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10619             } finally {
10620                 Binder.restoreCallingIdentity(ident);
10621             }
10622         }
10623     }
10624
10625     @Override
10626     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10627         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10628         if (StackId.isHomeOrRecentsStack(stackId)) {
10629             throw new IllegalArgumentException(
10630                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10631         }
10632         synchronized (this) {
10633             long ident = Binder.clearCallingIdentity();
10634             try {
10635                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10636                 if (task == null) {
10637                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10638                     return;
10639                 }
10640
10641                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10642                         + " to stackId=" + stackId + " toTop=" + toTop);
10643                 if (stackId == DOCKED_STACK_ID) {
10644                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10645                             null /* initialBounds */);
10646                 }
10647                 task.reparent(stackId, toTop,
10648                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10649             } finally {
10650                 Binder.restoreCallingIdentity(ident);
10651             }
10652         }
10653     }
10654
10655     @Override
10656     public void swapDockedAndFullscreenStack() throws RemoteException {
10657         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10658         synchronized (this) {
10659             long ident = Binder.clearCallingIdentity();
10660             try {
10661                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10662                         FULLSCREEN_WORKSPACE_STACK_ID);
10663                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10664                         : null;
10665                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10666                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10667                         : null;
10668                 if (topTask == null || tasks == null || tasks.size() == 0) {
10669                     Slog.w(TAG,
10670                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10671                     return;
10672                 }
10673
10674                 // TODO: App transition
10675                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10676
10677                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10678                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10679                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10680                 final int size = tasks.size();
10681                 for (int i = 0; i < size; i++) {
10682                     final int id = tasks.get(i).taskId;
10683                     if (id == topTask.taskId) {
10684                         continue;
10685                     }
10686
10687                     // Defer the resume until after all the tasks have been moved
10688                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10689                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10690                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10691                 }
10692
10693                 // Because we deferred the resume to avoid conflicts with stack switches while
10694                 // resuming, we need to do it after all the tasks are moved.
10695                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10696                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10697
10698                 mWindowManager.executeAppTransition();
10699             } finally {
10700                 Binder.restoreCallingIdentity(ident);
10701             }
10702         }
10703     }
10704
10705     /**
10706      * Moves the input task to the docked stack.
10707      *
10708      * @param taskId Id of task to move.
10709      * @param createMode The mode the docked stack should be created in if it doesn't exist
10710      *                   already. See
10711      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10712      *                   and
10713      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10714      * @param toTop If the task and stack should be moved to the top.
10715      * @param animate Whether we should play an animation for the moving the task
10716      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10717      *                      docked stack. Pass {@code null} to use default bounds.
10718      */
10719     @Override
10720     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10721             Rect initialBounds) {
10722         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10723         synchronized (this) {
10724             long ident = Binder.clearCallingIdentity();
10725             try {
10726                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10727                 if (task == null) {
10728                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10729                     return false;
10730                 }
10731
10732                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10733                         + " to createMode=" + createMode + " toTop=" + toTop);
10734                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10735
10736                 // Defer resuming until we move the home stack to the front below
10737                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10738                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10739                         "moveTaskToDockedStack");
10740                 if (moved) {
10741                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10742                 }
10743                 return moved;
10744             } finally {
10745                 Binder.restoreCallingIdentity(ident);
10746             }
10747         }
10748     }
10749
10750     /**
10751      * Moves the top activity in the input stackId to the pinned stack.
10752      *
10753      * @param stackId Id of stack to move the top activity to pinned stack.
10754      * @param bounds Bounds to use for pinned stack.
10755      *
10756      * @return True if the top activity of the input stack was successfully moved to the pinned
10757      *          stack.
10758      */
10759     @Override
10760     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10761         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10762         synchronized (this) {
10763             if (!mSupportsPictureInPicture) {
10764                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10765                         + "Device doesn't support picture-in-picture mode");
10766             }
10767
10768             long ident = Binder.clearCallingIdentity();
10769             try {
10770                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10771             } finally {
10772                 Binder.restoreCallingIdentity(ident);
10773             }
10774         }
10775     }
10776
10777     @Override
10778     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10779             boolean preserveWindows, boolean animate, int animationDuration) {
10780         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10781         long ident = Binder.clearCallingIdentity();
10782         try {
10783             synchronized (this) {
10784                 if (animate) {
10785                     if (stackId == PINNED_STACK_ID) {
10786                         final PinnedActivityStack pinnedStack =
10787                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10788                         if (pinnedStack != null) {
10789                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10790                                     destBounds, animationDuration, false /* fromFullscreen */);
10791                         }
10792                     } else {
10793                         throw new IllegalArgumentException("Stack: " + stackId
10794                                 + " doesn't support animated resize.");
10795                     }
10796                 } else {
10797                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10798                             null /* tempTaskInsetBounds */, preserveWindows,
10799                             allowResizeInDockedMode, !DEFER_RESUME);
10800                 }
10801             }
10802         } finally {
10803             Binder.restoreCallingIdentity(ident);
10804         }
10805     }
10806
10807     @Override
10808     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10809             Rect tempDockedTaskInsetBounds,
10810             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10811         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10812                 "resizeDockedStack()");
10813         long ident = Binder.clearCallingIdentity();
10814         try {
10815             synchronized (this) {
10816                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10817                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10818                         PRESERVE_WINDOWS);
10819             }
10820         } finally {
10821             Binder.restoreCallingIdentity(ident);
10822         }
10823     }
10824
10825     @Override
10826     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10827         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10828                 "resizePinnedStack()");
10829         final long ident = Binder.clearCallingIdentity();
10830         try {
10831             synchronized (this) {
10832                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10833             }
10834         } finally {
10835             Binder.restoreCallingIdentity(ident);
10836         }
10837     }
10838
10839     /**
10840      * Try to place task to provided position. The final position might be different depending on
10841      * current user and stacks state. The task will be moved to target stack if it's currently in
10842      * different stack.
10843      */
10844     @Override
10845     public void positionTaskInStack(int taskId, int stackId, int position) {
10846         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10847         if (StackId.isHomeOrRecentsStack(stackId)) {
10848             throw new IllegalArgumentException(
10849                     "positionTaskInStack: Attempt to change the position of task "
10850                     + taskId + " in/to home/recents stack");
10851         }
10852         synchronized (this) {
10853             long ident = Binder.clearCallingIdentity();
10854             try {
10855                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10856                         + taskId + " in stackId=" + stackId + " at position=" + position);
10857                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10858                 if (task == null) {
10859                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10860                             + taskId);
10861                 }
10862
10863                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10864                         !ON_TOP);
10865
10866                 // TODO: Have the callers of this API call a separate reparent method if that is
10867                 // what they intended to do vs. having this method also do reparenting.
10868                 if (task.getStack() == stack) {
10869                     // Change position in current stack.
10870                     stack.positionChildAt(task, position);
10871                 } else {
10872                     // Reparent to new stack.
10873                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10874                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10875                 }
10876             } finally {
10877                 Binder.restoreCallingIdentity(ident);
10878             }
10879         }
10880     }
10881
10882     @Override
10883     public List<StackInfo> getAllStackInfos() {
10884         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10885         long ident = Binder.clearCallingIdentity();
10886         try {
10887             synchronized (this) {
10888                 return mStackSupervisor.getAllStackInfosLocked();
10889             }
10890         } finally {
10891             Binder.restoreCallingIdentity(ident);
10892         }
10893     }
10894
10895     @Override
10896     public StackInfo getStackInfo(int stackId) {
10897         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10898         long ident = Binder.clearCallingIdentity();
10899         try {
10900             synchronized (this) {
10901                 return mStackSupervisor.getStackInfoLocked(stackId);
10902             }
10903         } finally {
10904             Binder.restoreCallingIdentity(ident);
10905         }
10906     }
10907
10908     @Override
10909     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10910         synchronized(this) {
10911             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10912         }
10913     }
10914
10915     @Override
10916     public void updateDeviceOwner(String packageName) {
10917         final int callingUid = Binder.getCallingUid();
10918         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10919             throw new SecurityException("updateDeviceOwner called from non-system process");
10920         }
10921         synchronized (this) {
10922             mDeviceOwnerName = packageName;
10923         }
10924     }
10925
10926     @Override
10927     public void updateLockTaskPackages(int userId, String[] packages) {
10928         final int callingUid = Binder.getCallingUid();
10929         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10930             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10931                     "updateLockTaskPackages()");
10932         }
10933         synchronized (this) {
10934             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10935                     Arrays.toString(packages));
10936             mLockTaskPackages.put(userId, packages);
10937             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10938         }
10939     }
10940
10941
10942     void startLockTaskModeLocked(TaskRecord task) {
10943         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10944         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10945             return;
10946         }
10947
10948         // When a task is locked, dismiss the pinned stack if it exists
10949         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10950                 PINNED_STACK_ID);
10951         if (pinnedStack != null) {
10952             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10953         }
10954
10955         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10956         // is initiated by system after the pinning request was shown and locked mode is initiated
10957         // by an authorized app directly
10958         final int callingUid = Binder.getCallingUid();
10959         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10960         long ident = Binder.clearCallingIdentity();
10961         try {
10962             if (!isSystemInitiated) {
10963                 task.mLockTaskUid = callingUid;
10964                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10965                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10966                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10967                     StatusBarManagerInternal statusBarManager =
10968                             LocalServices.getService(StatusBarManagerInternal.class);
10969                     if (statusBarManager != null) {
10970                         statusBarManager.showScreenPinningRequest(task.taskId);
10971                     }
10972                     return;
10973                 }
10974
10975                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10976                 if (stack == null || task != stack.topTask()) {
10977                     throw new IllegalArgumentException("Invalid task, not in foreground");
10978                 }
10979             }
10980             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10981                     "Locking fully");
10982             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10983                     ActivityManager.LOCK_TASK_MODE_PINNED :
10984                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10985                     "startLockTask", true);
10986         } finally {
10987             Binder.restoreCallingIdentity(ident);
10988         }
10989     }
10990
10991     @Override
10992     public void startLockTaskModeById(int taskId) {
10993         synchronized (this) {
10994             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10995             if (task != null) {
10996                 startLockTaskModeLocked(task);
10997             }
10998         }
10999     }
11000
11001     @Override
11002     public void startLockTaskModeByToken(IBinder token) {
11003         synchronized (this) {
11004             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11005             if (r == null) {
11006                 return;
11007             }
11008             final TaskRecord task = r.getTask();
11009             if (task != null) {
11010                 startLockTaskModeLocked(task);
11011             }
11012         }
11013     }
11014
11015     @Override
11016     public void startSystemLockTaskMode(int taskId) throws RemoteException {
11017         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11018         // This makes inner call to look as if it was initiated by system.
11019         long ident = Binder.clearCallingIdentity();
11020         try {
11021             synchronized (this) {
11022                 startLockTaskModeById(taskId);
11023             }
11024         } finally {
11025             Binder.restoreCallingIdentity(ident);
11026         }
11027     }
11028
11029     @Override
11030     public void stopLockTaskMode() {
11031         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11032         if (lockTask == null) {
11033             // Our work here is done.
11034             return;
11035         }
11036
11037         final int callingUid = Binder.getCallingUid();
11038         final int lockTaskUid = lockTask.mLockTaskUid;
11039         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11040         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11041             // Done.
11042             return;
11043         } else {
11044             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11045             // It is possible lockTaskMode was started by the system process because
11046             // android:lockTaskMode is set to a locking value in the application manifest
11047             // instead of the app calling startLockTaskMode. In this case
11048             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11049             // {@link TaskRecord.effectiveUid} instead. Also caller with
11050             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11051             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11052                     && callingUid != lockTaskUid
11053                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11054                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11055                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11056             }
11057         }
11058         long ident = Binder.clearCallingIdentity();
11059         try {
11060             Log.d(TAG, "stopLockTaskMode");
11061             // Stop lock task
11062             synchronized (this) {
11063                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11064                         "stopLockTask", true);
11065             }
11066             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11067             if (tm != null) {
11068                 tm.showInCallScreen(false);
11069             }
11070         } finally {
11071             Binder.restoreCallingIdentity(ident);
11072         }
11073     }
11074
11075     /**
11076      * This API should be called by SystemUI only when user perform certain action to dismiss
11077      * lock task mode. We should only dismiss pinned lock task mode in this case.
11078      */
11079     @Override
11080     public void stopSystemLockTaskMode() throws RemoteException {
11081         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11082             stopLockTaskMode();
11083         } else {
11084             mStackSupervisor.showLockTaskToast();
11085         }
11086     }
11087
11088     @Override
11089     public boolean isInLockTaskMode() {
11090         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11091     }
11092
11093     @Override
11094     public int getLockTaskModeState() {
11095         synchronized (this) {
11096             return mStackSupervisor.getLockTaskModeState();
11097         }
11098     }
11099
11100     @Override
11101     public void showLockTaskEscapeMessage(IBinder token) {
11102         synchronized (this) {
11103             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11104             if (r == null) {
11105                 return;
11106             }
11107             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11108         }
11109     }
11110
11111     @Override
11112     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11113             throws RemoteException {
11114         synchronized (this) {
11115             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11116             if (r == null) {
11117                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11118                         + token);
11119                 return;
11120             }
11121             final long origId = Binder.clearCallingIdentity();
11122             try {
11123                 r.setDisablePreviewScreenshots(disable);
11124             } finally {
11125                 Binder.restoreCallingIdentity(origId);
11126             }
11127         }
11128     }
11129
11130     // =========================================================
11131     // CONTENT PROVIDERS
11132     // =========================================================
11133
11134     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11135         List<ProviderInfo> providers = null;
11136         try {
11137             providers = AppGlobals.getPackageManager()
11138                     .queryContentProviders(app.processName, app.uid,
11139                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11140                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11141                     .getList();
11142         } catch (RemoteException ex) {
11143         }
11144         if (DEBUG_MU) Slog.v(TAG_MU,
11145                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11146         int userId = app.userId;
11147         if (providers != null) {
11148             int N = providers.size();
11149             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11150             for (int i=0; i<N; i++) {
11151                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11152                 ProviderInfo cpi =
11153                     (ProviderInfo)providers.get(i);
11154                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11155                         cpi.name, cpi.flags);
11156                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11157                     // This is a singleton provider, but a user besides the
11158                     // default user is asking to initialize a process it runs
11159                     // in...  well, no, it doesn't actually run in this process,
11160                     // it runs in the process of the default user.  Get rid of it.
11161                     providers.remove(i);
11162                     N--;
11163                     i--;
11164                     continue;
11165                 }
11166
11167                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11168                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11169                 if (cpr == null) {
11170                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11171                     mProviderMap.putProviderByClass(comp, cpr);
11172                 }
11173                 if (DEBUG_MU) Slog.v(TAG_MU,
11174                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11175                 app.pubProviders.put(cpi.name, cpr);
11176                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11177                     // Don't add this if it is a platform component that is marked
11178                     // to run in multiple processes, because this is actually
11179                     // part of the framework so doesn't make sense to track as a
11180                     // separate apk in the process.
11181                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11182                             mProcessStats);
11183                 }
11184                 notifyPackageUse(cpi.applicationInfo.packageName,
11185                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11186             }
11187         }
11188         return providers;
11189     }
11190
11191     /**
11192      * Check if the calling UID has a possible chance at accessing the provider
11193      * at the given authority and user.
11194      */
11195     public String checkContentProviderAccess(String authority, int userId) {
11196         if (userId == UserHandle.USER_ALL) {
11197             mContext.enforceCallingOrSelfPermission(
11198                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11199             userId = UserHandle.getCallingUserId();
11200         }
11201
11202         ProviderInfo cpi = null;
11203         try {
11204             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11205                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11206                             | PackageManager.MATCH_DISABLED_COMPONENTS
11207                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11208                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11209                     userId);
11210         } catch (RemoteException ignored) {
11211         }
11212         if (cpi == null) {
11213             return "Failed to find provider " + authority + " for user " + userId
11214                     + "; expected to find a valid ContentProvider for this authority";
11215         }
11216
11217         ProcessRecord r = null;
11218         synchronized (mPidsSelfLocked) {
11219             r = mPidsSelfLocked.get(Binder.getCallingPid());
11220         }
11221         if (r == null) {
11222             return "Failed to find PID " + Binder.getCallingPid();
11223         }
11224
11225         synchronized (this) {
11226             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11227         }
11228     }
11229
11230     /**
11231      * Check if {@link ProcessRecord} has a possible chance at accessing the
11232      * given {@link ProviderInfo}. Final permission checking is always done
11233      * in {@link ContentProvider}.
11234      */
11235     private final String checkContentProviderPermissionLocked(
11236             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11237         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11238         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11239         boolean checkedGrants = false;
11240         if (checkUser) {
11241             // Looking for cross-user grants before enforcing the typical cross-users permissions
11242             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11243             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11244                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11245                     return null;
11246                 }
11247                 checkedGrants = true;
11248             }
11249             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11250                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11251             if (userId != tmpTargetUserId) {
11252                 // When we actually went to determine the final targer user ID, this ended
11253                 // up different than our initial check for the authority.  This is because
11254                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11255                 // SELF.  So we need to re-check the grants again.
11256                 checkedGrants = false;
11257             }
11258         }
11259         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11260                 cpi.applicationInfo.uid, cpi.exported)
11261                 == PackageManager.PERMISSION_GRANTED) {
11262             return null;
11263         }
11264         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11265                 cpi.applicationInfo.uid, cpi.exported)
11266                 == PackageManager.PERMISSION_GRANTED) {
11267             return null;
11268         }
11269
11270         PathPermission[] pps = cpi.pathPermissions;
11271         if (pps != null) {
11272             int i = pps.length;
11273             while (i > 0) {
11274                 i--;
11275                 PathPermission pp = pps[i];
11276                 String pprperm = pp.getReadPermission();
11277                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11278                         cpi.applicationInfo.uid, cpi.exported)
11279                         == PackageManager.PERMISSION_GRANTED) {
11280                     return null;
11281                 }
11282                 String ppwperm = pp.getWritePermission();
11283                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11284                         cpi.applicationInfo.uid, cpi.exported)
11285                         == PackageManager.PERMISSION_GRANTED) {
11286                     return null;
11287                 }
11288             }
11289         }
11290         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11291             return null;
11292         }
11293
11294         final String suffix;
11295         if (!cpi.exported) {
11296             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11297         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11298             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11299         } else {
11300             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11301         }
11302         final String msg = "Permission Denial: opening provider " + cpi.name
11303                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11304                 + ", uid=" + callingUid + ")" + suffix;
11305         Slog.w(TAG, msg);
11306         return msg;
11307     }
11308
11309     /**
11310      * Returns if the ContentProvider has granted a uri to callingUid
11311      */
11312     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11313         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11314         if (perms != null) {
11315             for (int i=perms.size()-1; i>=0; i--) {
11316                 GrantUri grantUri = perms.keyAt(i);
11317                 if (grantUri.sourceUserId == userId || !checkUser) {
11318                     if (matchesProvider(grantUri.uri, cpi)) {
11319                         return true;
11320                     }
11321                 }
11322             }
11323         }
11324         return false;
11325     }
11326
11327     /**
11328      * Returns true if the uri authority is one of the authorities specified in the provider.
11329      */
11330     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11331         String uriAuth = uri.getAuthority();
11332         String cpiAuth = cpi.authority;
11333         if (cpiAuth.indexOf(';') == -1) {
11334             return cpiAuth.equals(uriAuth);
11335         }
11336         String[] cpiAuths = cpiAuth.split(";");
11337         int length = cpiAuths.length;
11338         for (int i = 0; i < length; i++) {
11339             if (cpiAuths[i].equals(uriAuth)) return true;
11340         }
11341         return false;
11342     }
11343
11344     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11345             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11346         if (r != null) {
11347             for (int i=0; i<r.conProviders.size(); i++) {
11348                 ContentProviderConnection conn = r.conProviders.get(i);
11349                 if (conn.provider == cpr) {
11350                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11351                             "Adding provider requested by "
11352                             + r.processName + " from process "
11353                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11354                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11355                     if (stable) {
11356                         conn.stableCount++;
11357                         conn.numStableIncs++;
11358                     } else {
11359                         conn.unstableCount++;
11360                         conn.numUnstableIncs++;
11361                     }
11362                     return conn;
11363                 }
11364             }
11365             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11366             if (stable) {
11367                 conn.stableCount = 1;
11368                 conn.numStableIncs = 1;
11369             } else {
11370                 conn.unstableCount = 1;
11371                 conn.numUnstableIncs = 1;
11372             }
11373             cpr.connections.add(conn);
11374             r.conProviders.add(conn);
11375             startAssociationLocked(r.uid, r.processName, r.curProcState,
11376                     cpr.uid, cpr.name, cpr.info.processName);
11377             return conn;
11378         }
11379         cpr.addExternalProcessHandleLocked(externalProcessToken);
11380         return null;
11381     }
11382
11383     boolean decProviderCountLocked(ContentProviderConnection conn,
11384             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11385         if (conn != null) {
11386             cpr = conn.provider;
11387             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11388                     "Removing provider requested by "
11389                     + conn.client.processName + " from process "
11390                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11391                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11392             if (stable) {
11393                 conn.stableCount--;
11394             } else {
11395                 conn.unstableCount--;
11396             }
11397             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11398                 cpr.connections.remove(conn);
11399                 conn.client.conProviders.remove(conn);
11400                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11401                     // The client is more important than last activity -- note the time this
11402                     // is happening, so we keep the old provider process around a bit as last
11403                     // activity to avoid thrashing it.
11404                     if (cpr.proc != null) {
11405                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11406                     }
11407                 }
11408                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11409                 return true;
11410             }
11411             return false;
11412         }
11413         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11414         return false;
11415     }
11416
11417     private void checkTime(long startTime, String where) {
11418         long now = SystemClock.uptimeMillis();
11419         if ((now-startTime) > 50) {
11420             // If we are taking more than 50ms, log about it.
11421             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11422         }
11423     }
11424
11425     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11426             PROC_SPACE_TERM,
11427             PROC_SPACE_TERM|PROC_PARENS,
11428             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11429     };
11430
11431     private final long[] mProcessStateStatsLongs = new long[1];
11432
11433     boolean isProcessAliveLocked(ProcessRecord proc) {
11434         if (proc.procStatFile == null) {
11435             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11436         }
11437         mProcessStateStatsLongs[0] = 0;
11438         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11439                 mProcessStateStatsLongs, null)) {
11440             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11441             return false;
11442         }
11443         final long state = mProcessStateStatsLongs[0];
11444         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11445                 + (char)state);
11446         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11447     }
11448
11449     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11450             String name, IBinder token, boolean stable, int userId) {
11451         ContentProviderRecord cpr;
11452         ContentProviderConnection conn = null;
11453         ProviderInfo cpi = null;
11454
11455         synchronized(this) {
11456             long startTime = SystemClock.uptimeMillis();
11457
11458             ProcessRecord r = null;
11459             if (caller != null) {
11460                 r = getRecordForAppLocked(caller);
11461                 if (r == null) {
11462                     throw new SecurityException(
11463                             "Unable to find app for caller " + caller
11464                           + " (pid=" + Binder.getCallingPid()
11465                           + ") when getting content provider " + name);
11466                 }
11467             }
11468
11469             boolean checkCrossUser = true;
11470
11471             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11472
11473             // First check if this content provider has been published...
11474             cpr = mProviderMap.getProviderByName(name, userId);
11475             // If that didn't work, check if it exists for user 0 and then
11476             // verify that it's a singleton provider before using it.
11477             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11478                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11479                 if (cpr != null) {
11480                     cpi = cpr.info;
11481                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11482                             cpi.name, cpi.flags)
11483                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11484                         userId = UserHandle.USER_SYSTEM;
11485                         checkCrossUser = false;
11486                     } else {
11487                         cpr = null;
11488                         cpi = null;
11489                     }
11490                 }
11491             }
11492
11493             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11494             if (providerRunning) {
11495                 cpi = cpr.info;
11496                 String msg;
11497                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11498                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11499                         != null) {
11500                     throw new SecurityException(msg);
11501                 }
11502                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11503
11504                 if (r != null && cpr.canRunHere(r)) {
11505                     // This provider has been published or is in the process
11506                     // of being published...  but it is also allowed to run
11507                     // in the caller's process, so don't make a connection
11508                     // and just let the caller instantiate its own instance.
11509                     ContentProviderHolder holder = cpr.newHolder(null);
11510                     // don't give caller the provider object, it needs
11511                     // to make its own.
11512                     holder.provider = null;
11513                     return holder;
11514                 }
11515                 // Don't expose providers between normal apps and instant apps
11516                 try {
11517                     if (AppGlobals.getPackageManager()
11518                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11519                         return null;
11520                     }
11521                 } catch (RemoteException e) {
11522                 }
11523
11524                 final long origId = Binder.clearCallingIdentity();
11525
11526                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11527
11528                 // In this case the provider instance already exists, so we can
11529                 // return it right away.
11530                 conn = incProviderCountLocked(r, cpr, token, stable);
11531                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11532                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11533                         // If this is a perceptible app accessing the provider,
11534                         // make sure to count it as being accessed and thus
11535                         // back up on the LRU list.  This is good because
11536                         // content providers are often expensive to start.
11537                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11538                         updateLruProcessLocked(cpr.proc, false, null);
11539                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11540                     }
11541                 }
11542
11543                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11544                 final int verifiedAdj = cpr.proc.verifiedAdj;
11545                 boolean success = updateOomAdjLocked(cpr.proc, true);
11546                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11547                 // if the process has been successfully adjusted.  So to reduce races with
11548                 // it, we will check whether the process still exists.  Note that this doesn't
11549                 // completely get rid of races with LMK killing the process, but should make
11550                 // them much smaller.
11551                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11552                     success = false;
11553                 }
11554                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11555                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11556                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11557                 // NOTE: there is still a race here where a signal could be
11558                 // pending on the process even though we managed to update its
11559                 // adj level.  Not sure what to do about this, but at least
11560                 // the race is now smaller.
11561                 if (!success) {
11562                     // Uh oh...  it looks like the provider's process
11563                     // has been killed on us.  We need to wait for a new
11564                     // process to be started, and make sure its death
11565                     // doesn't kill our process.
11566                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11567                             + " is crashing; detaching " + r);
11568                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11569                     checkTime(startTime, "getContentProviderImpl: before appDied");
11570                     appDiedLocked(cpr.proc);
11571                     checkTime(startTime, "getContentProviderImpl: after appDied");
11572                     if (!lastRef) {
11573                         // This wasn't the last ref our process had on
11574                         // the provider...  we have now been killed, bail.
11575                         return null;
11576                     }
11577                     providerRunning = false;
11578                     conn = null;
11579                 } else {
11580                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11581                 }
11582
11583                 Binder.restoreCallingIdentity(origId);
11584             }
11585
11586             if (!providerRunning) {
11587                 try {
11588                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11589                     cpi = AppGlobals.getPackageManager().
11590                         resolveContentProvider(name,
11591                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11592                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11593                 } catch (RemoteException ex) {
11594                 }
11595                 if (cpi == null) {
11596                     return null;
11597                 }
11598                 // If the provider is a singleton AND
11599                 // (it's a call within the same user || the provider is a
11600                 // privileged app)
11601                 // Then allow connecting to the singleton provider
11602                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11603                         cpi.name, cpi.flags)
11604                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11605                 if (singleton) {
11606                     userId = UserHandle.USER_SYSTEM;
11607                 }
11608                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11609                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11610
11611                 String msg;
11612                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11613                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11614                         != null) {
11615                     throw new SecurityException(msg);
11616                 }
11617                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11618
11619                 if (!mProcessesReady
11620                         && !cpi.processName.equals("system")) {
11621                     // If this content provider does not run in the system
11622                     // process, and the system is not yet ready to run other
11623                     // processes, then fail fast instead of hanging.
11624                     throw new IllegalArgumentException(
11625                             "Attempt to launch content provider before system ready");
11626                 }
11627
11628                 // Make sure that the user who owns this provider is running.  If not,
11629                 // we don't want to allow it to run.
11630                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11631                     Slog.w(TAG, "Unable to launch app "
11632                             + cpi.applicationInfo.packageName + "/"
11633                             + cpi.applicationInfo.uid + " for provider "
11634                             + name + ": user " + userId + " is stopped");
11635                     return null;
11636                 }
11637
11638                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11639                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11640                 cpr = mProviderMap.getProviderByClass(comp, userId);
11641                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11642                 final boolean firstClass = cpr == null;
11643                 if (firstClass) {
11644                     final long ident = Binder.clearCallingIdentity();
11645
11646                     // If permissions need a review before any of the app components can run,
11647                     // we return no provider and launch a review activity if the calling app
11648                     // is in the foreground.
11649                     if (mPermissionReviewRequired) {
11650                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11651                             return null;
11652                         }
11653                     }
11654
11655                     try {
11656                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11657                         ApplicationInfo ai =
11658                             AppGlobals.getPackageManager().
11659                                 getApplicationInfo(
11660                                         cpi.applicationInfo.packageName,
11661                                         STOCK_PM_FLAGS, userId);
11662                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11663                         if (ai == null) {
11664                             Slog.w(TAG, "No package info for content provider "
11665                                     + cpi.name);
11666                             return null;
11667                         }
11668                         ai = getAppInfoForUser(ai, userId);
11669                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11670                     } catch (RemoteException ex) {
11671                         // pm is in same process, this will never happen.
11672                     } finally {
11673                         Binder.restoreCallingIdentity(ident);
11674                     }
11675                 }
11676
11677                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11678
11679                 if (r != null && cpr.canRunHere(r)) {
11680                     // If this is a multiprocess provider, then just return its
11681                     // info and allow the caller to instantiate it.  Only do
11682                     // this if the provider is the same user as the caller's
11683                     // process, or can run as root (so can be in any process).
11684                     return cpr.newHolder(null);
11685                 }
11686
11687                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11688                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11689                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11690
11691                 // This is single process, and our app is now connecting to it.
11692                 // See if we are already in the process of launching this
11693                 // provider.
11694                 final int N = mLaunchingProviders.size();
11695                 int i;
11696                 for (i = 0; i < N; i++) {
11697                     if (mLaunchingProviders.get(i) == cpr) {
11698                         break;
11699                     }
11700                 }
11701
11702                 // If the provider is not already being launched, then get it
11703                 // started.
11704                 if (i >= N) {
11705                     final long origId = Binder.clearCallingIdentity();
11706
11707                     try {
11708                         // Content provider is now in use, its package can't be stopped.
11709                         try {
11710                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11711                             AppGlobals.getPackageManager().setPackageStoppedState(
11712                                     cpr.appInfo.packageName, false, userId);
11713                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11714                         } catch (RemoteException e) {
11715                         } catch (IllegalArgumentException e) {
11716                             Slog.w(TAG, "Failed trying to unstop package "
11717                                     + cpr.appInfo.packageName + ": " + e);
11718                         }
11719
11720                         // Use existing process if already started
11721                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11722                         ProcessRecord proc = getProcessRecordLocked(
11723                                 cpi.processName, cpr.appInfo.uid, false);
11724                         if (proc != null && proc.thread != null && !proc.killed) {
11725                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11726                                     "Installing in existing process " + proc);
11727                             if (!proc.pubProviders.containsKey(cpi.name)) {
11728                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11729                                 proc.pubProviders.put(cpi.name, cpr);
11730                                 try {
11731                                     proc.thread.scheduleInstallProvider(cpi);
11732                                 } catch (RemoteException e) {
11733                                 }
11734                             }
11735                         } else {
11736                             checkTime(startTime, "getContentProviderImpl: before start process");
11737                             proc = startProcessLocked(cpi.processName,
11738                                     cpr.appInfo, false, 0, "content provider",
11739                                     new ComponentName(cpi.applicationInfo.packageName,
11740                                             cpi.name), false, false, false);
11741                             checkTime(startTime, "getContentProviderImpl: after start process");
11742                             if (proc == null) {
11743                                 Slog.w(TAG, "Unable to launch app "
11744                                         + cpi.applicationInfo.packageName + "/"
11745                                         + cpi.applicationInfo.uid + " for provider "
11746                                         + name + ": process is bad");
11747                                 return null;
11748                             }
11749                         }
11750                         cpr.launchingApp = proc;
11751                         mLaunchingProviders.add(cpr);
11752                     } finally {
11753                         Binder.restoreCallingIdentity(origId);
11754                     }
11755                 }
11756
11757                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11758
11759                 // Make sure the provider is published (the same provider class
11760                 // may be published under multiple names).
11761                 if (firstClass) {
11762                     mProviderMap.putProviderByClass(comp, cpr);
11763                 }
11764
11765                 mProviderMap.putProviderByName(name, cpr);
11766                 conn = incProviderCountLocked(r, cpr, token, stable);
11767                 if (conn != null) {
11768                     conn.waiting = true;
11769                 }
11770             }
11771             checkTime(startTime, "getContentProviderImpl: done!");
11772
11773             grantEphemeralAccessLocked(userId, null /*intent*/,
11774                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11775         }
11776
11777         // Wait for the provider to be published...
11778         synchronized (cpr) {
11779             while (cpr.provider == null) {
11780                 if (cpr.launchingApp == null) {
11781                     Slog.w(TAG, "Unable to launch app "
11782                             + cpi.applicationInfo.packageName + "/"
11783                             + cpi.applicationInfo.uid + " for provider "
11784                             + name + ": launching app became null");
11785                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11786                             UserHandle.getUserId(cpi.applicationInfo.uid),
11787                             cpi.applicationInfo.packageName,
11788                             cpi.applicationInfo.uid, name);
11789                     return null;
11790                 }
11791                 try {
11792                     if (DEBUG_MU) Slog.v(TAG_MU,
11793                             "Waiting to start provider " + cpr
11794                             + " launchingApp=" + cpr.launchingApp);
11795                     if (conn != null) {
11796                         conn.waiting = true;
11797                     }
11798                     cpr.wait();
11799                 } catch (InterruptedException ex) {
11800                 } finally {
11801                     if (conn != null) {
11802                         conn.waiting = false;
11803                     }
11804                 }
11805             }
11806         }
11807         return cpr != null ? cpr.newHolder(conn) : null;
11808     }
11809
11810     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11811             ProcessRecord r, final int userId) {
11812         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11813                 cpi.packageName, userId)) {
11814
11815             final boolean callerForeground = r == null || r.setSchedGroup
11816                     != ProcessList.SCHED_GROUP_BACKGROUND;
11817
11818             // Show a permission review UI only for starting from a foreground app
11819             if (!callerForeground) {
11820                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11821                         + cpi.packageName + " requires a permissions review");
11822                 return false;
11823             }
11824
11825             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11826             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11827                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11828             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11829
11830             if (DEBUG_PERMISSIONS_REVIEW) {
11831                 Slog.i(TAG, "u" + userId + " Launching permission review "
11832                         + "for package " + cpi.packageName);
11833             }
11834
11835             final UserHandle userHandle = new UserHandle(userId);
11836             mHandler.post(new Runnable() {
11837                 @Override
11838                 public void run() {
11839                     mContext.startActivityAsUser(intent, userHandle);
11840                 }
11841             });
11842
11843             return false;
11844         }
11845
11846         return true;
11847     }
11848
11849     PackageManagerInternal getPackageManagerInternalLocked() {
11850         if (mPackageManagerInt == null) {
11851             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11852         }
11853         return mPackageManagerInt;
11854     }
11855
11856     @Override
11857     public final ContentProviderHolder getContentProvider(
11858             IApplicationThread caller, String name, int userId, boolean stable) {
11859         enforceNotIsolatedCaller("getContentProvider");
11860         if (caller == null) {
11861             String msg = "null IApplicationThread when getting content provider "
11862                     + name;
11863             Slog.w(TAG, msg);
11864             throw new SecurityException(msg);
11865         }
11866         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11867         // with cross-user grant.
11868         return getContentProviderImpl(caller, name, null, stable, userId);
11869     }
11870
11871     public ContentProviderHolder getContentProviderExternal(
11872             String name, int userId, IBinder token) {
11873         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11874             "Do not have permission in call getContentProviderExternal()");
11875         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11876                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11877         return getContentProviderExternalUnchecked(name, token, userId);
11878     }
11879
11880     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11881             IBinder token, int userId) {
11882         return getContentProviderImpl(null, name, token, true, userId);
11883     }
11884
11885     /**
11886      * Drop a content provider from a ProcessRecord's bookkeeping
11887      */
11888     public void removeContentProvider(IBinder connection, boolean stable) {
11889         enforceNotIsolatedCaller("removeContentProvider");
11890         long ident = Binder.clearCallingIdentity();
11891         try {
11892             synchronized (this) {
11893                 ContentProviderConnection conn;
11894                 try {
11895                     conn = (ContentProviderConnection)connection;
11896                 } catch (ClassCastException e) {
11897                     String msg ="removeContentProvider: " + connection
11898                             + " not a ContentProviderConnection";
11899                     Slog.w(TAG, msg);
11900                     throw new IllegalArgumentException(msg);
11901                 }
11902                 if (conn == null) {
11903                     throw new NullPointerException("connection is null");
11904                 }
11905                 if (decProviderCountLocked(conn, null, null, stable)) {
11906                     updateOomAdjLocked();
11907                 }
11908             }
11909         } finally {
11910             Binder.restoreCallingIdentity(ident);
11911         }
11912     }
11913
11914     public void removeContentProviderExternal(String name, IBinder token) {
11915         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11916             "Do not have permission in call removeContentProviderExternal()");
11917         int userId = UserHandle.getCallingUserId();
11918         long ident = Binder.clearCallingIdentity();
11919         try {
11920             removeContentProviderExternalUnchecked(name, token, userId);
11921         } finally {
11922             Binder.restoreCallingIdentity(ident);
11923         }
11924     }
11925
11926     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11927         synchronized (this) {
11928             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11929             if(cpr == null) {
11930                 //remove from mProvidersByClass
11931                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11932                 return;
11933             }
11934
11935             //update content provider record entry info
11936             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11937             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11938             if (localCpr.hasExternalProcessHandles()) {
11939                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11940                     updateOomAdjLocked();
11941                 } else {
11942                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11943                             + " with no external reference for token: "
11944                             + token + ".");
11945                 }
11946             } else {
11947                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11948                         + " with no external references.");
11949             }
11950         }
11951     }
11952
11953     public final void publishContentProviders(IApplicationThread caller,
11954             List<ContentProviderHolder> providers) {
11955         if (providers == null) {
11956             return;
11957         }
11958
11959         enforceNotIsolatedCaller("publishContentProviders");
11960         synchronized (this) {
11961             final ProcessRecord r = getRecordForAppLocked(caller);
11962             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11963             if (r == null) {
11964                 throw new SecurityException(
11965                         "Unable to find app for caller " + caller
11966                       + " (pid=" + Binder.getCallingPid()
11967                       + ") when publishing content providers");
11968             }
11969
11970             final long origId = Binder.clearCallingIdentity();
11971
11972             final int N = providers.size();
11973             for (int i = 0; i < N; i++) {
11974                 ContentProviderHolder src = providers.get(i);
11975                 if (src == null || src.info == null || src.provider == null) {
11976                     continue;
11977                 }
11978                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11979                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11980                 if (dst != null) {
11981                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11982                     mProviderMap.putProviderByClass(comp, dst);
11983                     String names[] = dst.info.authority.split(";");
11984                     for (int j = 0; j < names.length; j++) {
11985                         mProviderMap.putProviderByName(names[j], dst);
11986                     }
11987
11988                     int launchingCount = mLaunchingProviders.size();
11989                     int j;
11990                     boolean wasInLaunchingProviders = false;
11991                     for (j = 0; j < launchingCount; j++) {
11992                         if (mLaunchingProviders.get(j) == dst) {
11993                             mLaunchingProviders.remove(j);
11994                             wasInLaunchingProviders = true;
11995                             j--;
11996                             launchingCount--;
11997                         }
11998                     }
11999                     if (wasInLaunchingProviders) {
12000                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12001                     }
12002                     synchronized (dst) {
12003                         dst.provider = src.provider;
12004                         dst.proc = r;
12005                         dst.notifyAll();
12006                     }
12007                     updateOomAdjLocked(r, true);
12008                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12009                             src.info.authority);
12010                 }
12011             }
12012
12013             Binder.restoreCallingIdentity(origId);
12014         }
12015     }
12016
12017     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12018         ContentProviderConnection conn;
12019         try {
12020             conn = (ContentProviderConnection)connection;
12021         } catch (ClassCastException e) {
12022             String msg ="refContentProvider: " + connection
12023                     + " not a ContentProviderConnection";
12024             Slog.w(TAG, msg);
12025             throw new IllegalArgumentException(msg);
12026         }
12027         if (conn == null) {
12028             throw new NullPointerException("connection is null");
12029         }
12030
12031         synchronized (this) {
12032             if (stable > 0) {
12033                 conn.numStableIncs += stable;
12034             }
12035             stable = conn.stableCount + stable;
12036             if (stable < 0) {
12037                 throw new IllegalStateException("stableCount < 0: " + stable);
12038             }
12039
12040             if (unstable > 0) {
12041                 conn.numUnstableIncs += unstable;
12042             }
12043             unstable = conn.unstableCount + unstable;
12044             if (unstable < 0) {
12045                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12046             }
12047
12048             if ((stable+unstable) <= 0) {
12049                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12050                         + stable + " unstable=" + unstable);
12051             }
12052             conn.stableCount = stable;
12053             conn.unstableCount = unstable;
12054             return !conn.dead;
12055         }
12056     }
12057
12058     public void unstableProviderDied(IBinder connection) {
12059         ContentProviderConnection conn;
12060         try {
12061             conn = (ContentProviderConnection)connection;
12062         } catch (ClassCastException e) {
12063             String msg ="refContentProvider: " + connection
12064                     + " not a ContentProviderConnection";
12065             Slog.w(TAG, msg);
12066             throw new IllegalArgumentException(msg);
12067         }
12068         if (conn == null) {
12069             throw new NullPointerException("connection is null");
12070         }
12071
12072         // Safely retrieve the content provider associated with the connection.
12073         IContentProvider provider;
12074         synchronized (this) {
12075             provider = conn.provider.provider;
12076         }
12077
12078         if (provider == null) {
12079             // Um, yeah, we're way ahead of you.
12080             return;
12081         }
12082
12083         // Make sure the caller is being honest with us.
12084         if (provider.asBinder().pingBinder()) {
12085             // Er, no, still looks good to us.
12086             synchronized (this) {
12087                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12088                         + " says " + conn + " died, but we don't agree");
12089                 return;
12090             }
12091         }
12092
12093         // Well look at that!  It's dead!
12094         synchronized (this) {
12095             if (conn.provider.provider != provider) {
12096                 // But something changed...  good enough.
12097                 return;
12098             }
12099
12100             ProcessRecord proc = conn.provider.proc;
12101             if (proc == null || proc.thread == null) {
12102                 // Seems like the process is already cleaned up.
12103                 return;
12104             }
12105
12106             // As far as we're concerned, this is just like receiving a
12107             // death notification...  just a bit prematurely.
12108             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12109                     + ") early provider death");
12110             final long ident = Binder.clearCallingIdentity();
12111             try {
12112                 appDiedLocked(proc);
12113             } finally {
12114                 Binder.restoreCallingIdentity(ident);
12115             }
12116         }
12117     }
12118
12119     @Override
12120     public void appNotRespondingViaProvider(IBinder connection) {
12121         enforceCallingPermission(
12122                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12123
12124         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12125         if (conn == null) {
12126             Slog.w(TAG, "ContentProviderConnection is null");
12127             return;
12128         }
12129
12130         final ProcessRecord host = conn.provider.proc;
12131         if (host == null) {
12132             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12133             return;
12134         }
12135
12136         mHandler.post(new Runnable() {
12137             @Override
12138             public void run() {
12139                 mAppErrors.appNotResponding(host, null, null, false,
12140                         "ContentProvider not responding");
12141             }
12142         });
12143     }
12144
12145     public final void installSystemProviders() {
12146         List<ProviderInfo> providers;
12147         synchronized (this) {
12148             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12149             providers = generateApplicationProvidersLocked(app);
12150             if (providers != null) {
12151                 for (int i=providers.size()-1; i>=0; i--) {
12152                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12153                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12154                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12155                                 + ": not system .apk");
12156                         providers.remove(i);
12157                     }
12158                 }
12159             }
12160         }
12161         if (providers != null) {
12162             mSystemThread.installSystemProviders(providers);
12163         }
12164
12165         mConstants.start(mContext.getContentResolver());
12166         mCoreSettingsObserver = new CoreSettingsObserver(this);
12167         mFontScaleSettingObserver = new FontScaleSettingObserver();
12168
12169         // Now that the settings provider is published we can consider sending
12170         // in a rescue party.
12171         RescueParty.onSettingsProviderPublished(mContext);
12172
12173         //mUsageStatsService.monitorPackages();
12174     }
12175
12176     private void startPersistentApps(int matchFlags) {
12177         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12178
12179         synchronized (this) {
12180             try {
12181                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12182                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12183                 for (ApplicationInfo app : apps) {
12184                     if (!"android".equals(app.packageName)) {
12185                         addAppLocked(app, null, false, null /* ABI override */);
12186                     }
12187                 }
12188             } catch (RemoteException ex) {
12189             }
12190         }
12191     }
12192
12193     /**
12194      * When a user is unlocked, we need to install encryption-unaware providers
12195      * belonging to any running apps.
12196      */
12197     private void installEncryptionUnawareProviders(int userId) {
12198         // We're only interested in providers that are encryption unaware, and
12199         // we don't care about uninstalled apps, since there's no way they're
12200         // running at this point.
12201         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12202
12203         synchronized (this) {
12204             final int NP = mProcessNames.getMap().size();
12205             for (int ip = 0; ip < NP; ip++) {
12206                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12207                 final int NA = apps.size();
12208                 for (int ia = 0; ia < NA; ia++) {
12209                     final ProcessRecord app = apps.valueAt(ia);
12210                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12211
12212                     final int NG = app.pkgList.size();
12213                     for (int ig = 0; ig < NG; ig++) {
12214                         try {
12215                             final String pkgName = app.pkgList.keyAt(ig);
12216                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12217                                     .getPackageInfo(pkgName, matchFlags, userId);
12218                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12219                                 for (ProviderInfo pi : pkgInfo.providers) {
12220                                     // TODO: keep in sync with generateApplicationProvidersLocked
12221                                     final boolean processMatch = Objects.equals(pi.processName,
12222                                             app.processName) || pi.multiprocess;
12223                                     final boolean userMatch = isSingleton(pi.processName,
12224                                             pi.applicationInfo, pi.name, pi.flags)
12225                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12226                                     if (processMatch && userMatch) {
12227                                         Log.v(TAG, "Installing " + pi);
12228                                         app.thread.scheduleInstallProvider(pi);
12229                                     } else {
12230                                         Log.v(TAG, "Skipping " + pi);
12231                                     }
12232                                 }
12233                             }
12234                         } catch (RemoteException ignored) {
12235                         }
12236                     }
12237                 }
12238             }
12239         }
12240     }
12241
12242     /**
12243      * Allows apps to retrieve the MIME type of a URI.
12244      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12245      * users, then it does not need permission to access the ContentProvider.
12246      * Either, it needs cross-user uri grants.
12247      *
12248      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12249      *
12250      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12251      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12252      */
12253     public String getProviderMimeType(Uri uri, int userId) {
12254         enforceNotIsolatedCaller("getProviderMimeType");
12255         final String name = uri.getAuthority();
12256         int callingUid = Binder.getCallingUid();
12257         int callingPid = Binder.getCallingPid();
12258         long ident = 0;
12259         boolean clearedIdentity = false;
12260         synchronized (this) {
12261             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12262         }
12263         if (canClearIdentity(callingPid, callingUid, userId)) {
12264             clearedIdentity = true;
12265             ident = Binder.clearCallingIdentity();
12266         }
12267         ContentProviderHolder holder = null;
12268         try {
12269             holder = getContentProviderExternalUnchecked(name, null, userId);
12270             if (holder != null) {
12271                 return holder.provider.getType(uri);
12272             }
12273         } catch (RemoteException e) {
12274             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12275             return null;
12276         } catch (Exception e) {
12277             Log.w(TAG, "Exception while determining type of " + uri, e);
12278             return null;
12279         } finally {
12280             // We need to clear the identity to call removeContentProviderExternalUnchecked
12281             if (!clearedIdentity) {
12282                 ident = Binder.clearCallingIdentity();
12283             }
12284             try {
12285                 if (holder != null) {
12286                     removeContentProviderExternalUnchecked(name, null, userId);
12287                 }
12288             } finally {
12289                 Binder.restoreCallingIdentity(ident);
12290             }
12291         }
12292
12293         return null;
12294     }
12295
12296     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12297         if (UserHandle.getUserId(callingUid) == userId) {
12298             return true;
12299         }
12300         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12301                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12302                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12303                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12304                 return true;
12305         }
12306         return false;
12307     }
12308
12309     // =========================================================
12310     // GLOBAL MANAGEMENT
12311     // =========================================================
12312
12313     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12314             boolean isolated, int isolatedUid) {
12315         String proc = customProcess != null ? customProcess : info.processName;
12316         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12317         final int userId = UserHandle.getUserId(info.uid);
12318         int uid = info.uid;
12319         if (isolated) {
12320             if (isolatedUid == 0) {
12321                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12322                 while (true) {
12323                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12324                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12325                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12326                     }
12327                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12328                     mNextIsolatedProcessUid++;
12329                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12330                         // No process for this uid, use it.
12331                         break;
12332                     }
12333                     stepsLeft--;
12334                     if (stepsLeft <= 0) {
12335                         return null;
12336                     }
12337                 }
12338             } else {
12339                 // Special case for startIsolatedProcess (internal only), where
12340                 // the uid of the isolated process is specified by the caller.
12341                 uid = isolatedUid;
12342             }
12343             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12344
12345             // Register the isolated UID with this application so BatteryStats knows to
12346             // attribute resource usage to the application.
12347             //
12348             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12349             // about the process state of the isolated UID *before* it is registered with the
12350             // owning application.
12351             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12352         }
12353         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12354         if (!mBooted && !mBooting
12355                 && userId == UserHandle.USER_SYSTEM
12356                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12357             r.persistent = true;
12358             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12359         }
12360         addProcessNameLocked(r);
12361         return r;
12362     }
12363
12364     private boolean uidOnBackgroundWhitelist(final int uid) {
12365         final int appId = UserHandle.getAppId(uid);
12366         final int[] whitelist = mBackgroundAppIdWhitelist;
12367         final int N = whitelist.length;
12368         for (int i = 0; i < N; i++) {
12369             if (appId == whitelist[i]) {
12370                 return true;
12371             }
12372         }
12373         return false;
12374     }
12375
12376     @Override
12377     public void backgroundWhitelistUid(final int uid) {
12378         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12379             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12380         }
12381
12382         if (DEBUG_BACKGROUND_CHECK) {
12383             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12384         }
12385         synchronized (this) {
12386             final int N = mBackgroundAppIdWhitelist.length;
12387             int[] newList = new int[N+1];
12388             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12389             newList[N] = UserHandle.getAppId(uid);
12390             mBackgroundAppIdWhitelist = newList;
12391         }
12392     }
12393
12394     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12395             String abiOverride) {
12396         ProcessRecord app;
12397         if (!isolated) {
12398             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12399                     info.uid, true);
12400         } else {
12401             app = null;
12402         }
12403
12404         if (app == null) {
12405             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12406             updateLruProcessLocked(app, false, null);
12407             updateOomAdjLocked();
12408         }
12409
12410         // This package really, really can not be stopped.
12411         try {
12412             AppGlobals.getPackageManager().setPackageStoppedState(
12413                     info.packageName, false, UserHandle.getUserId(app.uid));
12414         } catch (RemoteException e) {
12415         } catch (IllegalArgumentException e) {
12416             Slog.w(TAG, "Failed trying to unstop package "
12417                     + info.packageName + ": " + e);
12418         }
12419
12420         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12421             app.persistent = true;
12422             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12423         }
12424         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12425             mPersistentStartingProcesses.add(app);
12426             startProcessLocked(app, "added application",
12427                     customProcess != null ? customProcess : app.processName, abiOverride,
12428                     null /* entryPoint */, null /* entryPointArgs */);
12429         }
12430
12431         return app;
12432     }
12433
12434     public void unhandledBack() {
12435         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12436                 "unhandledBack()");
12437
12438         synchronized(this) {
12439             final long origId = Binder.clearCallingIdentity();
12440             try {
12441                 getFocusedStack().unhandledBackLocked();
12442             } finally {
12443                 Binder.restoreCallingIdentity(origId);
12444             }
12445         }
12446     }
12447
12448     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12449         enforceNotIsolatedCaller("openContentUri");
12450         final int userId = UserHandle.getCallingUserId();
12451         final Uri uri = Uri.parse(uriString);
12452         String name = uri.getAuthority();
12453         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12454         ParcelFileDescriptor pfd = null;
12455         if (cph != null) {
12456             // We record the binder invoker's uid in thread-local storage before
12457             // going to the content provider to open the file.  Later, in the code
12458             // that handles all permissions checks, we look for this uid and use
12459             // that rather than the Activity Manager's own uid.  The effect is that
12460             // we do the check against the caller's permissions even though it looks
12461             // to the content provider like the Activity Manager itself is making
12462             // the request.
12463             Binder token = new Binder();
12464             sCallerIdentity.set(new Identity(
12465                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12466             try {
12467                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12468             } catch (FileNotFoundException e) {
12469                 // do nothing; pfd will be returned null
12470             } finally {
12471                 // Ensure that whatever happens, we clean up the identity state
12472                 sCallerIdentity.remove();
12473                 // Ensure we're done with the provider.
12474                 removeContentProviderExternalUnchecked(name, null, userId);
12475             }
12476         } else {
12477             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12478         }
12479         return pfd;
12480     }
12481
12482     // Actually is sleeping or shutting down or whatever else in the future
12483     // is an inactive state.
12484     boolean isSleepingOrShuttingDownLocked() {
12485         return isSleepingLocked() || mShuttingDown;
12486     }
12487
12488     boolean isShuttingDownLocked() {
12489         return mShuttingDown;
12490     }
12491
12492     boolean isSleepingLocked() {
12493         return mSleeping;
12494     }
12495
12496     void onWakefulnessChanged(int wakefulness) {
12497         synchronized(this) {
12498             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12499             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12500             mWakefulness = wakefulness;
12501
12502             if (wasAwake != isAwake) {
12503                 // Also update state in a special way for running foreground services UI.
12504                 mServices.updateScreenStateLocked(isAwake);
12505                 sendNotifyVrManagerOfSleepState(!isAwake);
12506             }
12507         }
12508     }
12509
12510     void finishRunningVoiceLocked() {
12511         if (mRunningVoice != null) {
12512             mRunningVoice = null;
12513             mVoiceWakeLock.release();
12514             updateSleepIfNeededLocked();
12515         }
12516     }
12517
12518     void startTimeTrackingFocusedActivityLocked() {
12519         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12520         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12521             mCurAppTimeTracker.start(resumedActivity.packageName);
12522         }
12523     }
12524
12525     void updateSleepIfNeededLocked() {
12526         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12527         final boolean wasSleeping = mSleeping;
12528
12529         if (!shouldSleep) {
12530             // If wasSleeping is true, we need to wake up activity manager state from when
12531             // we started sleeping. In either case, we need to apply the sleep tokens, which
12532             // will wake up stacks or put them to sleep as appropriate.
12533             if (wasSleeping) {
12534                 mSleeping = false;
12535                 startTimeTrackingFocusedActivityLocked();
12536                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12537                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12538             }
12539             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12540             if (wasSleeping) {
12541                 updateOomAdjLocked();
12542             }
12543         } else if (!mSleeping && shouldSleep) {
12544             mSleeping = true;
12545             if (mCurAppTimeTracker != null) {
12546                 mCurAppTimeTracker.stop();
12547             }
12548             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12549             mStackSupervisor.goingToSleepLocked();
12550             updateOomAdjLocked();
12551         }
12552     }
12553
12554     /** Pokes the task persister. */
12555     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12556         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12557     }
12558
12559     /**
12560      * Notifies all listeners when the pinned stack animation starts.
12561      */
12562     @Override
12563     public void notifyPinnedStackAnimationStarted() {
12564         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12565     }
12566
12567     /**
12568      * Notifies all listeners when the pinned stack animation ends.
12569      */
12570     @Override
12571     public void notifyPinnedStackAnimationEnded() {
12572         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12573     }
12574
12575     @Override
12576     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12577         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12578     }
12579
12580     @Override
12581     public boolean shutdown(int timeout) {
12582         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12583                 != PackageManager.PERMISSION_GRANTED) {
12584             throw new SecurityException("Requires permission "
12585                     + android.Manifest.permission.SHUTDOWN);
12586         }
12587
12588         boolean timedout = false;
12589
12590         synchronized(this) {
12591             mShuttingDown = true;
12592             mStackSupervisor.prepareForShutdownLocked();
12593             updateEventDispatchingLocked();
12594             timedout = mStackSupervisor.shutdownLocked(timeout);
12595         }
12596
12597         mAppOpsService.shutdown();
12598         if (mUsageStatsService != null) {
12599             mUsageStatsService.prepareShutdown();
12600         }
12601         mBatteryStatsService.shutdown();
12602         synchronized (this) {
12603             mProcessStats.shutdownLocked();
12604             notifyTaskPersisterLocked(null, true);
12605         }
12606
12607         return timedout;
12608     }
12609
12610     public final void activitySlept(IBinder token) {
12611         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12612
12613         final long origId = Binder.clearCallingIdentity();
12614
12615         synchronized (this) {
12616             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12617             if (r != null) {
12618                 mStackSupervisor.activitySleptLocked(r);
12619             }
12620         }
12621
12622         Binder.restoreCallingIdentity(origId);
12623     }
12624
12625     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12626         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12627         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12628         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12629             boolean wasRunningVoice = mRunningVoice != null;
12630             mRunningVoice = session;
12631             if (!wasRunningVoice) {
12632                 mVoiceWakeLock.acquire();
12633                 updateSleepIfNeededLocked();
12634             }
12635         }
12636     }
12637
12638     private void updateEventDispatchingLocked() {
12639         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12640     }
12641
12642     @Override
12643     public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12644         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12645                 != PackageManager.PERMISSION_GRANTED) {
12646             throw new SecurityException("Requires permission "
12647                     + android.Manifest.permission.DEVICE_POWER);
12648         }
12649
12650         synchronized(this) {
12651             long ident = Binder.clearCallingIdentity();
12652             try {
12653                 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12654             } finally {
12655                 Binder.restoreCallingIdentity(ident);
12656             }
12657         }
12658         sendNotifyVrManagerOfKeyguardState(showing);
12659     }
12660
12661     @Override
12662     public void notifyLockedProfile(@UserIdInt int userId) {
12663         try {
12664             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12665                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12666             }
12667         } catch (RemoteException ex) {
12668             throw new SecurityException("Fail to check is caller a privileged app", ex);
12669         }
12670
12671         synchronized (this) {
12672             final long ident = Binder.clearCallingIdentity();
12673             try {
12674                 if (mUserController.shouldConfirmCredentials(userId)) {
12675                     if (mKeyguardController.isKeyguardLocked()) {
12676                         // Showing launcher to avoid user entering credential twice.
12677                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12678                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12679                     }
12680                     mStackSupervisor.lockAllProfileTasks(userId);
12681                 }
12682             } finally {
12683                 Binder.restoreCallingIdentity(ident);
12684             }
12685         }
12686     }
12687
12688     @Override
12689     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12690         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12691         synchronized (this) {
12692             final long ident = Binder.clearCallingIdentity();
12693             try {
12694                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12695             } finally {
12696                 Binder.restoreCallingIdentity(ident);
12697             }
12698         }
12699     }
12700
12701     @Override
12702     public void stopAppSwitches() {
12703         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12704                 != PackageManager.PERMISSION_GRANTED) {
12705             throw new SecurityException("viewquires permission "
12706                     + android.Manifest.permission.STOP_APP_SWITCHES);
12707         }
12708
12709         synchronized(this) {
12710             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12711                     + APP_SWITCH_DELAY_TIME;
12712             mDidAppSwitch = false;
12713             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12714             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12715             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12716         }
12717     }
12718
12719     public void resumeAppSwitches() {
12720         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12721                 != PackageManager.PERMISSION_GRANTED) {
12722             throw new SecurityException("Requires permission "
12723                     + android.Manifest.permission.STOP_APP_SWITCHES);
12724         }
12725
12726         synchronized(this) {
12727             // Note that we don't execute any pending app switches... we will
12728             // let those wait until either the timeout, or the next start
12729             // activity request.
12730             mAppSwitchesAllowedTime = 0;
12731         }
12732     }
12733
12734     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12735             int callingPid, int callingUid, String name) {
12736         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12737             return true;
12738         }
12739
12740         int perm = checkComponentPermission(
12741                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12742                 sourceUid, -1, true);
12743         if (perm == PackageManager.PERMISSION_GRANTED) {
12744             return true;
12745         }
12746
12747         // If the actual IPC caller is different from the logical source, then
12748         // also see if they are allowed to control app switches.
12749         if (callingUid != -1 && callingUid != sourceUid) {
12750             perm = checkComponentPermission(
12751                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12752                     callingUid, -1, true);
12753             if (perm == PackageManager.PERMISSION_GRANTED) {
12754                 return true;
12755             }
12756         }
12757
12758         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12759         return false;
12760     }
12761
12762     public void setDebugApp(String packageName, boolean waitForDebugger,
12763             boolean persistent) {
12764         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12765                 "setDebugApp()");
12766
12767         long ident = Binder.clearCallingIdentity();
12768         try {
12769             // Note that this is not really thread safe if there are multiple
12770             // callers into it at the same time, but that's not a situation we
12771             // care about.
12772             if (persistent) {
12773                 final ContentResolver resolver = mContext.getContentResolver();
12774                 Settings.Global.putString(
12775                     resolver, Settings.Global.DEBUG_APP,
12776                     packageName);
12777                 Settings.Global.putInt(
12778                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12779                     waitForDebugger ? 1 : 0);
12780             }
12781
12782             synchronized (this) {
12783                 if (!persistent) {
12784                     mOrigDebugApp = mDebugApp;
12785                     mOrigWaitForDebugger = mWaitForDebugger;
12786                 }
12787                 mDebugApp = packageName;
12788                 mWaitForDebugger = waitForDebugger;
12789                 mDebugTransient = !persistent;
12790                 if (packageName != null) {
12791                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12792                             false, UserHandle.USER_ALL, "set debug app");
12793                 }
12794             }
12795         } finally {
12796             Binder.restoreCallingIdentity(ident);
12797         }
12798     }
12799
12800     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12801         synchronized (this) {
12802             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12803             if (!isDebuggable) {
12804                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12805                     throw new SecurityException("Process not debuggable: " + app.packageName);
12806                 }
12807             }
12808
12809             mTrackAllocationApp = processName;
12810         }
12811     }
12812
12813     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12814         synchronized (this) {
12815             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12816             if (!isDebuggable) {
12817                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12818                     throw new SecurityException("Process not debuggable: " + app.packageName);
12819                 }
12820             }
12821             mProfileApp = processName;
12822
12823             if (mProfilerInfo != null) {
12824                 if (mProfilerInfo.profileFd != null) {
12825                     try {
12826                         mProfilerInfo.profileFd.close();
12827                     } catch (IOException e) {
12828                     }
12829                 }
12830             }
12831             mProfilerInfo = new ProfilerInfo(profilerInfo);
12832             mProfileType = 0;
12833         }
12834     }
12835
12836     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12837         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12838         if (!isDebuggable) {
12839             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12840                 throw new SecurityException("Process not debuggable: " + app.packageName);
12841             }
12842         }
12843         mNativeDebuggingApp = processName;
12844     }
12845
12846     @Override
12847     public void setAlwaysFinish(boolean enabled) {
12848         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12849                 "setAlwaysFinish()");
12850
12851         long ident = Binder.clearCallingIdentity();
12852         try {
12853             Settings.Global.putInt(
12854                     mContext.getContentResolver(),
12855                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12856
12857             synchronized (this) {
12858                 mAlwaysFinishActivities = enabled;
12859             }
12860         } finally {
12861             Binder.restoreCallingIdentity(ident);
12862         }
12863     }
12864
12865     @Override
12866     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12867         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12868                 "setActivityController()");
12869         synchronized (this) {
12870             mController = controller;
12871             mControllerIsAMonkey = imAMonkey;
12872             Watchdog.getInstance().setActivityController(controller);
12873         }
12874     }
12875
12876     @Override
12877     public void setUserIsMonkey(boolean userIsMonkey) {
12878         synchronized (this) {
12879             synchronized (mPidsSelfLocked) {
12880                 final int callingPid = Binder.getCallingPid();
12881                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12882                 if (proc == null) {
12883                     throw new SecurityException("Unknown process: " + callingPid);
12884                 }
12885                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12886                     throw new SecurityException("Only an instrumentation process "
12887                             + "with a UiAutomation can call setUserIsMonkey");
12888                 }
12889             }
12890             mUserIsMonkey = userIsMonkey;
12891         }
12892     }
12893
12894     @Override
12895     public boolean isUserAMonkey() {
12896         synchronized (this) {
12897             // If there is a controller also implies the user is a monkey.
12898             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12899         }
12900     }
12901
12902     /**
12903      * @deprecated This method is only used by a few internal components and it will soon be
12904      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12905      * No new code should be calling it.
12906      */
12907     @Deprecated
12908     @Override
12909     public void requestBugReport(int bugreportType) {
12910         String extraOptions = null;
12911         switch (bugreportType) {
12912             case ActivityManager.BUGREPORT_OPTION_FULL:
12913                 // Default options.
12914                 break;
12915             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12916                 extraOptions = "bugreportplus";
12917                 break;
12918             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12919                 extraOptions = "bugreportremote";
12920                 break;
12921             case ActivityManager.BUGREPORT_OPTION_WEAR:
12922                 extraOptions = "bugreportwear";
12923                 break;
12924             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12925                 extraOptions = "bugreporttelephony";
12926                 break;
12927             default:
12928                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12929                         + bugreportType);
12930         }
12931         // Always log caller, even if it does not have permission to dump.
12932         String type = extraOptions == null ? "bugreport" : extraOptions;
12933         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12934
12935         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12936         if (extraOptions != null) {
12937             SystemProperties.set("dumpstate.options", extraOptions);
12938         }
12939         SystemProperties.set("ctl.start", "bugreport");
12940     }
12941
12942     /**
12943      * @deprecated This method is only used by a few internal components and it will soon be
12944      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12945      * No new code should be calling it.
12946      */
12947     @Deprecated
12948     @Override
12949     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12950
12951         if (!TextUtils.isEmpty(shareTitle)) {
12952             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12953                 String errorStr = "shareTitle should be less than " +
12954                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12955                 throw new IllegalArgumentException(errorStr);
12956             } else {
12957                 if (!TextUtils.isEmpty(shareDescription)) {
12958                     int length;
12959                     try {
12960                         length = shareDescription.getBytes("UTF-8").length;
12961                     } catch (UnsupportedEncodingException e) {
12962                         String errorStr = "shareDescription: UnsupportedEncodingException";
12963                         throw new IllegalArgumentException(errorStr);
12964                     }
12965                     if (length > SystemProperties.PROP_VALUE_MAX) {
12966                         String errorStr = "shareTitle should be less than " +
12967                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12968                         throw new IllegalArgumentException(errorStr);
12969                     } else {
12970                         SystemProperties.set("dumpstate.options.description", shareDescription);
12971                     }
12972                 }
12973                 SystemProperties.set("dumpstate.options.title", shareTitle);
12974             }
12975         }
12976
12977         Slog.d(TAG, "Bugreport notification title " + shareTitle
12978                 + " description " + shareDescription);
12979         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12980     }
12981
12982     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12983         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12984     }
12985
12986     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12987         if (r != null && (r.instr != null || r.usingWrapper)) {
12988             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12989         }
12990         return KEY_DISPATCHING_TIMEOUT;
12991     }
12992
12993     @Override
12994     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12995         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12996                 != PackageManager.PERMISSION_GRANTED) {
12997             throw new SecurityException("Requires permission "
12998                     + android.Manifest.permission.FILTER_EVENTS);
12999         }
13000         ProcessRecord proc;
13001         long timeout;
13002         synchronized (this) {
13003             synchronized (mPidsSelfLocked) {
13004                 proc = mPidsSelfLocked.get(pid);
13005             }
13006             timeout = getInputDispatchingTimeoutLocked(proc);
13007         }
13008
13009         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13010             return -1;
13011         }
13012
13013         return timeout;
13014     }
13015
13016     /**
13017      * Handle input dispatching timeouts.
13018      * Returns whether input dispatching should be aborted or not.
13019      */
13020     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13021             final ActivityRecord activity, final ActivityRecord parent,
13022             final boolean aboveSystem, String reason) {
13023         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13024                 != PackageManager.PERMISSION_GRANTED) {
13025             throw new SecurityException("Requires permission "
13026                     + android.Manifest.permission.FILTER_EVENTS);
13027         }
13028
13029         final String annotation;
13030         if (reason == null) {
13031             annotation = "Input dispatching timed out";
13032         } else {
13033             annotation = "Input dispatching timed out (" + reason + ")";
13034         }
13035
13036         if (proc != null) {
13037             synchronized (this) {
13038                 if (proc.debugging) {
13039                     return false;
13040                 }
13041
13042                 if (proc.instr != null) {
13043                     Bundle info = new Bundle();
13044                     info.putString("shortMsg", "keyDispatchingTimedOut");
13045                     info.putString("longMsg", annotation);
13046                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13047                     return true;
13048                 }
13049             }
13050             mHandler.post(new Runnable() {
13051                 @Override
13052                 public void run() {
13053                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13054                 }
13055             });
13056         }
13057
13058         return true;
13059     }
13060
13061     @Override
13062     public Bundle getAssistContextExtras(int requestType) {
13063         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13064                 null, null, true /* focused */, true /* newSessionId */,
13065                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13066         if (pae == null) {
13067             return null;
13068         }
13069         synchronized (pae) {
13070             while (!pae.haveResult) {
13071                 try {
13072                     pae.wait();
13073                 } catch (InterruptedException e) {
13074                 }
13075             }
13076         }
13077         synchronized (this) {
13078             buildAssistBundleLocked(pae, pae.result);
13079             mPendingAssistExtras.remove(pae);
13080             mUiHandler.removeCallbacks(pae);
13081         }
13082         return pae.extras;
13083     }
13084
13085     @Override
13086     public boolean isAssistDataAllowedOnCurrentActivity() {
13087         int userId;
13088         synchronized (this) {
13089             final ActivityStack focusedStack = getFocusedStack();
13090             if (focusedStack == null || focusedStack.isAssistantStack()) {
13091                 return false;
13092             }
13093
13094             final ActivityRecord activity = focusedStack.topActivity();
13095             if (activity == null) {
13096                 return false;
13097             }
13098             userId = activity.userId;
13099         }
13100         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13101                 Context.DEVICE_POLICY_SERVICE);
13102         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13103     }
13104
13105     @Override
13106     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13107         long ident = Binder.clearCallingIdentity();
13108         try {
13109             synchronized (this) {
13110                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13111                 ActivityRecord top = getFocusedStack().topActivity();
13112                 if (top != caller) {
13113                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13114                             + " is not current top " + top);
13115                     return false;
13116                 }
13117                 if (!top.nowVisible) {
13118                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13119                             + " is not visible");
13120                     return false;
13121                 }
13122             }
13123             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13124                     token);
13125         } finally {
13126             Binder.restoreCallingIdentity(ident);
13127         }
13128     }
13129
13130     @Override
13131     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13132             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13133         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13134                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13135                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13136     }
13137
13138     @Override
13139     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13140             IBinder activityToken, int flags) {
13141         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13142                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13143                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13144     }
13145
13146     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13147             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13148             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13149             int flags) {
13150         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13151                 "enqueueAssistContext()");
13152
13153         synchronized (this) {
13154             ActivityRecord activity = getFocusedStack().topActivity();
13155             if (activity == null) {
13156                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13157                 return null;
13158             }
13159             if (activity.app == null || activity.app.thread == null) {
13160                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13161                 return null;
13162             }
13163             if (focused) {
13164                 if (activityToken != null) {
13165                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13166                     if (activity != caller) {
13167                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13168                                 + " is not current top " + activity);
13169                         return null;
13170                     }
13171                 }
13172             } else {
13173                 activity = ActivityRecord.forTokenLocked(activityToken);
13174                 if (activity == null) {
13175                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13176                             + " couldn't be found");
13177                     return null;
13178                 }
13179                 if (activity.app == null || activity.app.thread == null) {
13180                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13181                     return null;
13182                 }
13183             }
13184
13185             PendingAssistExtras pae;
13186             Bundle extras = new Bundle();
13187             if (args != null) {
13188                 extras.putAll(args);
13189             }
13190             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13191             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13192
13193             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13194                     userHandle);
13195             pae.isHome = activity.isHomeActivity();
13196
13197             // Increment the sessionId if necessary
13198             if (newSessionId) {
13199                 mViSessionId++;
13200             }
13201             try {
13202                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13203                         mViSessionId, flags);
13204                 mPendingAssistExtras.add(pae);
13205                 mUiHandler.postDelayed(pae, timeout);
13206             } catch (RemoteException e) {
13207                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13208                 return null;
13209             }
13210             return pae;
13211         }
13212     }
13213
13214     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13215         IResultReceiver receiver;
13216         synchronized (this) {
13217             mPendingAssistExtras.remove(pae);
13218             receiver = pae.receiver;
13219         }
13220         if (receiver != null) {
13221             // Caller wants result sent back to them.
13222             Bundle sendBundle = new Bundle();
13223             // At least return the receiver extras
13224             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13225                     pae.receiverExtras);
13226             try {
13227                 pae.receiver.send(0, sendBundle);
13228             } catch (RemoteException e) {
13229             }
13230         }
13231     }
13232
13233     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13234         if (result != null) {
13235             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13236         }
13237         if (pae.hint != null) {
13238             pae.extras.putBoolean(pae.hint, true);
13239         }
13240     }
13241
13242     /** Called from an app when assist data is ready. */
13243     @Override
13244     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13245             AssistContent content, Uri referrer) {
13246         PendingAssistExtras pae = (PendingAssistExtras)token;
13247         synchronized (pae) {
13248             pae.result = extras;
13249             pae.structure = structure;
13250             pae.content = content;
13251             if (referrer != null) {
13252                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13253             }
13254             if (structure != null) {
13255                 structure.setHomeActivity(pae.isHome);
13256             }
13257             pae.haveResult = true;
13258             pae.notifyAll();
13259             if (pae.intent == null && pae.receiver == null) {
13260                 // Caller is just waiting for the result.
13261                 return;
13262             }
13263         }
13264         // We are now ready to launch the assist activity.
13265         IResultReceiver sendReceiver = null;
13266         Bundle sendBundle = null;
13267         synchronized (this) {
13268             buildAssistBundleLocked(pae, extras);
13269             boolean exists = mPendingAssistExtras.remove(pae);
13270             mUiHandler.removeCallbacks(pae);
13271             if (!exists) {
13272                 // Timed out.
13273                 return;
13274             }
13275             if ((sendReceiver=pae.receiver) != null) {
13276                 // Caller wants result sent back to them.
13277                 sendBundle = new Bundle();
13278                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13279                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13280                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13281                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13282                         pae.receiverExtras);
13283             }
13284         }
13285         if (sendReceiver != null) {
13286             try {
13287                 sendReceiver.send(0, sendBundle);
13288             } catch (RemoteException e) {
13289             }
13290             return;
13291         }
13292
13293         final long ident = Binder.clearCallingIdentity();
13294         try {
13295             if (TextUtils.equals(pae.intent.getAction(),
13296                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13297                 pae.intent.putExtras(pae.extras);
13298                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13299             } else {
13300                 pae.intent.replaceExtras(pae.extras);
13301                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13302                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13303                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13304                 closeSystemDialogs("assist");
13305
13306                 try {
13307                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13308                 } catch (ActivityNotFoundException e) {
13309                     Slog.w(TAG, "No activity to handle assist action.", e);
13310                 }
13311             }
13312         } finally {
13313             Binder.restoreCallingIdentity(ident);
13314         }
13315     }
13316
13317     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13318             Bundle args) {
13319         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13320                 true /* focused */, true /* newSessionId */, userHandle, args,
13321                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13322     }
13323
13324     public void registerProcessObserver(IProcessObserver observer) {
13325         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13326                 "registerProcessObserver()");
13327         synchronized (this) {
13328             mProcessObservers.register(observer);
13329         }
13330     }
13331
13332     @Override
13333     public void unregisterProcessObserver(IProcessObserver observer) {
13334         synchronized (this) {
13335             mProcessObservers.unregister(observer);
13336         }
13337     }
13338
13339     @Override
13340     public int getUidProcessState(int uid, String callingPackage) {
13341         if (!hasUsageStatsPermission(callingPackage)) {
13342             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13343                     "getUidProcessState");
13344         }
13345
13346         synchronized (this) {
13347             UidRecord uidRec = mActiveUids.get(uid);
13348             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13349         }
13350     }
13351
13352     @Override
13353     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13354             String callingPackage) {
13355         if (!hasUsageStatsPermission(callingPackage)) {
13356             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13357                     "registerUidObserver");
13358         }
13359         synchronized (this) {
13360             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13361                     callingPackage, which, cutpoint));
13362         }
13363     }
13364
13365     @Override
13366     public void unregisterUidObserver(IUidObserver observer) {
13367         synchronized (this) {
13368             mUidObservers.unregister(observer);
13369         }
13370     }
13371
13372     @Override
13373     public boolean convertFromTranslucent(IBinder token) {
13374         final long origId = Binder.clearCallingIdentity();
13375         try {
13376             synchronized (this) {
13377                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13378                 if (r == null) {
13379                     return false;
13380                 }
13381                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13382                 if (translucentChanged) {
13383                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13384                 }
13385                 mWindowManager.setAppFullscreen(token, true);
13386                 return translucentChanged;
13387             }
13388         } finally {
13389             Binder.restoreCallingIdentity(origId);
13390         }
13391     }
13392
13393     @Override
13394     public boolean convertToTranslucent(IBinder token, Bundle options) {
13395         final long origId = Binder.clearCallingIdentity();
13396         try {
13397             synchronized (this) {
13398                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13399                 if (r == null) {
13400                     return false;
13401                 }
13402                 final TaskRecord task = r.getTask();
13403                 int index = task.mActivities.lastIndexOf(r);
13404                 if (index > 0) {
13405                     ActivityRecord under = task.mActivities.get(index - 1);
13406                     under.returningOptions = ActivityOptions.fromBundle(options);
13407                 }
13408                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13409                 if (translucentChanged) {
13410                     r.getStack().convertActivityToTranslucent(r);
13411                 }
13412                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13413                 mWindowManager.setAppFullscreen(token, false);
13414                 return translucentChanged;
13415             }
13416         } finally {
13417             Binder.restoreCallingIdentity(origId);
13418         }
13419     }
13420
13421     @Override
13422     public Bundle getActivityOptions(IBinder token) {
13423         final long origId = Binder.clearCallingIdentity();
13424         try {
13425             synchronized (this) {
13426                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13427                 if (r != null) {
13428                     final ActivityOptions activityOptions = r.takeOptionsLocked();
13429                     return activityOptions == null ? null : activityOptions.toBundle();
13430                 }
13431                 return null;
13432             }
13433         } finally {
13434             Binder.restoreCallingIdentity(origId);
13435         }
13436     }
13437
13438     @Override
13439     public void setImmersive(IBinder token, boolean immersive) {
13440         synchronized(this) {
13441             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13442             if (r == null) {
13443                 throw new IllegalArgumentException();
13444             }
13445             r.immersive = immersive;
13446
13447             // update associated state if we're frontmost
13448             if (r == mStackSupervisor.getResumedActivityLocked()) {
13449                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13450                 applyUpdateLockStateLocked(r);
13451             }
13452         }
13453     }
13454
13455     @Override
13456     public boolean isImmersive(IBinder token) {
13457         synchronized (this) {
13458             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13459             if (r == null) {
13460                 throw new IllegalArgumentException();
13461             }
13462             return r.immersive;
13463         }
13464     }
13465
13466     @Override
13467     public void setVrThread(int tid) {
13468         enforceSystemHasVrFeature();
13469         synchronized (this) {
13470             synchronized (mPidsSelfLocked) {
13471                 final int pid = Binder.getCallingPid();
13472                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13473                 mVrController.setVrThreadLocked(tid, pid, proc);
13474             }
13475         }
13476     }
13477
13478     @Override
13479     public void setPersistentVrThread(int tid) {
13480         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13481             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13482                     + Binder.getCallingPid()
13483                     + ", uid=" + Binder.getCallingUid()
13484                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13485             Slog.w(TAG, msg);
13486             throw new SecurityException(msg);
13487         }
13488         enforceSystemHasVrFeature();
13489         synchronized (this) {
13490             synchronized (mPidsSelfLocked) {
13491                 final int pid = Binder.getCallingPid();
13492                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13493                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13494             }
13495         }
13496     }
13497
13498     /**
13499      * Schedule the given thread a normal scheduling priority.
13500      *
13501      * @param tid the tid of the thread to adjust the scheduling of.
13502      * @param suppressLogs {@code true} if any error logging should be disabled.
13503      *
13504      * @return {@code true} if this succeeded.
13505      */
13506     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13507         try {
13508             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13509             return true;
13510         } catch (IllegalArgumentException e) {
13511             if (!suppressLogs) {
13512                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13513             }
13514         } catch (SecurityException e) {
13515             if (!suppressLogs) {
13516                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13517             }
13518         }
13519         return false;
13520     }
13521
13522     /**
13523      * Schedule the given thread an FIFO scheduling priority.
13524      *
13525      * @param tid the tid of the thread to adjust the scheduling of.
13526      * @param suppressLogs {@code true} if any error logging should be disabled.
13527      *
13528      * @return {@code true} if this succeeded.
13529      */
13530     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13531         try {
13532             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13533             return true;
13534         } catch (IllegalArgumentException e) {
13535             if (!suppressLogs) {
13536                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13537             }
13538         } catch (SecurityException e) {
13539             if (!suppressLogs) {
13540                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13541             }
13542         }
13543         return false;
13544     }
13545
13546     /**
13547      * Check that we have the features required for VR-related API calls, and throw an exception if
13548      * not.
13549      */
13550     private void enforceSystemHasVrFeature() {
13551         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13552             throw new UnsupportedOperationException("VR mode not supported on this device!");
13553         }
13554     }
13555
13556     @Override
13557     public void setRenderThread(int tid) {
13558         synchronized (this) {
13559             ProcessRecord proc;
13560             int pid = Binder.getCallingPid();
13561             if (pid == Process.myPid()) {
13562                 demoteSystemServerRenderThread(tid);
13563                 return;
13564             }
13565             synchronized (mPidsSelfLocked) {
13566                 proc = mPidsSelfLocked.get(pid);
13567                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13568                     // ensure the tid belongs to the process
13569                     if (!isThreadInProcess(pid, tid)) {
13570                         throw new IllegalArgumentException(
13571                             "Render thread does not belong to process");
13572                     }
13573                     proc.renderThreadTid = tid;
13574                     if (DEBUG_OOM_ADJ) {
13575                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13576                     }
13577                     // promote to FIFO now
13578                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13579                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13580                         if (mUseFifoUiScheduling) {
13581                             setThreadScheduler(proc.renderThreadTid,
13582                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13583                         } else {
13584                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13585                         }
13586                     }
13587                 } else {
13588                     if (DEBUG_OOM_ADJ) {
13589                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13590                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13591                                mUseFifoUiScheduling);
13592                     }
13593                 }
13594             }
13595         }
13596     }
13597
13598     /**
13599      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13600      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13601      *
13602      * @param tid the tid of the RenderThread
13603      */
13604     private void demoteSystemServerRenderThread(int tid) {
13605         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13606     }
13607
13608     @Override
13609     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13610         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13611             throw new UnsupportedOperationException("VR mode not supported on this device!");
13612         }
13613
13614         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13615
13616         ActivityRecord r;
13617         synchronized (this) {
13618             r = ActivityRecord.isInStackLocked(token);
13619         }
13620
13621         if (r == null) {
13622             throw new IllegalArgumentException();
13623         }
13624
13625         int err;
13626         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13627                 VrManagerInternal.NO_ERROR) {
13628             return err;
13629         }
13630
13631         synchronized(this) {
13632             r.requestedVrComponent = (enabled) ? packageName : null;
13633
13634             // Update associated state if this activity is currently focused
13635             if (r == mStackSupervisor.getResumedActivityLocked()) {
13636                 applyUpdateVrModeLocked(r);
13637             }
13638             return 0;
13639         }
13640     }
13641
13642     @Override
13643     public boolean isVrModePackageEnabled(ComponentName packageName) {
13644         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13645             throw new UnsupportedOperationException("VR mode not supported on this device!");
13646         }
13647
13648         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13649
13650         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13651                 VrManagerInternal.NO_ERROR;
13652     }
13653
13654     public boolean isTopActivityImmersive() {
13655         enforceNotIsolatedCaller("startActivity");
13656         synchronized (this) {
13657             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13658             return (r != null) ? r.immersive : false;
13659         }
13660     }
13661
13662     /**
13663      * @return whether the system should disable UI modes incompatible with VR mode.
13664      */
13665     boolean shouldDisableNonVrUiLocked() {
13666         return mVrController.shouldDisableNonVrUiLocked();
13667     }
13668
13669     @Override
13670     public boolean isTopOfTask(IBinder token) {
13671         synchronized (this) {
13672             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13673             if (r == null) {
13674                 throw new IllegalArgumentException();
13675             }
13676             return r.getTask().getTopActivity() == r;
13677         }
13678     }
13679
13680     @Override
13681     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13682         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13683             String msg = "Permission Denial: setHasTopUi() from pid="
13684                     + Binder.getCallingPid()
13685                     + ", uid=" + Binder.getCallingUid()
13686                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13687             Slog.w(TAG, msg);
13688             throw new SecurityException(msg);
13689         }
13690         final int pid = Binder.getCallingPid();
13691         final long origId = Binder.clearCallingIdentity();
13692         try {
13693             synchronized (this) {
13694                 boolean changed = false;
13695                 ProcessRecord pr;
13696                 synchronized (mPidsSelfLocked) {
13697                     pr = mPidsSelfLocked.get(pid);
13698                     if (pr == null) {
13699                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13700                         return;
13701                     }
13702                     if (pr.hasTopUi != hasTopUi) {
13703                         if (DEBUG_OOM_ADJ) {
13704                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13705                         }
13706                         pr.hasTopUi = hasTopUi;
13707                         changed = true;
13708                     }
13709                 }
13710                 if (changed) {
13711                     updateOomAdjLocked(pr, true);
13712                 }
13713             }
13714         } finally {
13715             Binder.restoreCallingIdentity(origId);
13716         }
13717     }
13718
13719     public final void enterSafeMode() {
13720         synchronized(this) {
13721             // It only makes sense to do this before the system is ready
13722             // and started launching other packages.
13723             if (!mSystemReady) {
13724                 try {
13725                     AppGlobals.getPackageManager().enterSafeMode();
13726                 } catch (RemoteException e) {
13727                 }
13728             }
13729
13730             mSafeMode = true;
13731         }
13732     }
13733
13734     public final void showSafeModeOverlay() {
13735         View v = LayoutInflater.from(mContext).inflate(
13736                 com.android.internal.R.layout.safe_mode, null);
13737         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13738         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13739         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13740         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13741         lp.gravity = Gravity.BOTTOM | Gravity.START;
13742         lp.format = v.getBackground().getOpacity();
13743         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13744                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13745         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13746         ((WindowManager)mContext.getSystemService(
13747                 Context.WINDOW_SERVICE)).addView(v, lp);
13748     }
13749
13750     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13751         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13752             return;
13753         }
13754         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13755         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13756         synchronized (stats) {
13757             if (mBatteryStatsService.isOnBattery()) {
13758                 mBatteryStatsService.enforceCallingPermission();
13759                 int MY_UID = Binder.getCallingUid();
13760                 final int uid;
13761                 if (sender == null) {
13762                     uid = sourceUid;
13763                 } else {
13764                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13765                 }
13766                 BatteryStatsImpl.Uid.Pkg pkg =
13767                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13768                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13769                 pkg.noteWakeupAlarmLocked(tag);
13770             }
13771         }
13772     }
13773
13774     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13775         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13776             return;
13777         }
13778         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13779         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13780         synchronized (stats) {
13781             mBatteryStatsService.enforceCallingPermission();
13782             int MY_UID = Binder.getCallingUid();
13783             final int uid;
13784             if (sender == null) {
13785                 uid = sourceUid;
13786             } else {
13787                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13788             }
13789             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13790         }
13791     }
13792
13793     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13794         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13795             return;
13796         }
13797         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13798         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13799         synchronized (stats) {
13800             mBatteryStatsService.enforceCallingPermission();
13801             int MY_UID = Binder.getCallingUid();
13802             final int uid;
13803             if (sender == null) {
13804                 uid = sourceUid;
13805             } else {
13806                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13807             }
13808             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13809         }
13810     }
13811
13812     public boolean killPids(int[] pids, String pReason, boolean secure) {
13813         if (Binder.getCallingUid() != SYSTEM_UID) {
13814             throw new SecurityException("killPids only available to the system");
13815         }
13816         String reason = (pReason == null) ? "Unknown" : pReason;
13817         // XXX Note: don't acquire main activity lock here, because the window
13818         // manager calls in with its locks held.
13819
13820         boolean killed = false;
13821         synchronized (mPidsSelfLocked) {
13822             int worstType = 0;
13823             for (int i=0; i<pids.length; i++) {
13824                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13825                 if (proc != null) {
13826                     int type = proc.setAdj;
13827                     if (type > worstType) {
13828                         worstType = type;
13829                     }
13830                 }
13831             }
13832
13833             // If the worst oom_adj is somewhere in the cached proc LRU range,
13834             // then constrain it so we will kill all cached procs.
13835             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13836                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13837                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13838             }
13839
13840             // If this is not a secure call, don't let it kill processes that
13841             // are important.
13842             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13843                 worstType = ProcessList.SERVICE_ADJ;
13844             }
13845
13846             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13847             for (int i=0; i<pids.length; i++) {
13848                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13849                 if (proc == null) {
13850                     continue;
13851                 }
13852                 int adj = proc.setAdj;
13853                 if (adj >= worstType && !proc.killedByAm) {
13854                     proc.kill(reason, true);
13855                     killed = true;
13856                 }
13857             }
13858         }
13859         return killed;
13860     }
13861
13862     @Override
13863     public void killUid(int appId, int userId, String reason) {
13864         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13865         synchronized (this) {
13866             final long identity = Binder.clearCallingIdentity();
13867             try {
13868                 killPackageProcessesLocked(null, appId, userId,
13869                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13870                         reason != null ? reason : "kill uid");
13871             } finally {
13872                 Binder.restoreCallingIdentity(identity);
13873             }
13874         }
13875     }
13876
13877     @Override
13878     public boolean killProcessesBelowForeground(String reason) {
13879         if (Binder.getCallingUid() != SYSTEM_UID) {
13880             throw new SecurityException("killProcessesBelowForeground() only available to system");
13881         }
13882
13883         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13884     }
13885
13886     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13887         if (Binder.getCallingUid() != SYSTEM_UID) {
13888             throw new SecurityException("killProcessesBelowAdj() only available to system");
13889         }
13890
13891         boolean killed = false;
13892         synchronized (mPidsSelfLocked) {
13893             final int size = mPidsSelfLocked.size();
13894             for (int i = 0; i < size; i++) {
13895                 final int pid = mPidsSelfLocked.keyAt(i);
13896                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13897                 if (proc == null) continue;
13898
13899                 final int adj = proc.setAdj;
13900                 if (adj > belowAdj && !proc.killedByAm) {
13901                     proc.kill(reason, true);
13902                     killed = true;
13903                 }
13904             }
13905         }
13906         return killed;
13907     }
13908
13909     @Override
13910     public void hang(final IBinder who, boolean allowRestart) {
13911         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13912                 != PackageManager.PERMISSION_GRANTED) {
13913             throw new SecurityException("Requires permission "
13914                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13915         }
13916
13917         final IBinder.DeathRecipient death = new DeathRecipient() {
13918             @Override
13919             public void binderDied() {
13920                 synchronized (this) {
13921                     notifyAll();
13922                 }
13923             }
13924         };
13925
13926         try {
13927             who.linkToDeath(death, 0);
13928         } catch (RemoteException e) {
13929             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13930             return;
13931         }
13932
13933         synchronized (this) {
13934             Watchdog.getInstance().setAllowRestart(allowRestart);
13935             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13936             synchronized (death) {
13937                 while (who.isBinderAlive()) {
13938                     try {
13939                         death.wait();
13940                     } catch (InterruptedException e) {
13941                     }
13942                 }
13943             }
13944             Watchdog.getInstance().setAllowRestart(true);
13945         }
13946     }
13947
13948     @Override
13949     public void restart() {
13950         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13951                 != PackageManager.PERMISSION_GRANTED) {
13952             throw new SecurityException("Requires permission "
13953                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13954         }
13955
13956         Log.i(TAG, "Sending shutdown broadcast...");
13957
13958         BroadcastReceiver br = new BroadcastReceiver() {
13959             @Override public void onReceive(Context context, Intent intent) {
13960                 // Now the broadcast is done, finish up the low-level shutdown.
13961                 Log.i(TAG, "Shutting down activity manager...");
13962                 shutdown(10000);
13963                 Log.i(TAG, "Shutdown complete, restarting!");
13964                 killProcess(myPid());
13965                 System.exit(10);
13966             }
13967         };
13968
13969         // First send the high-level shut down broadcast.
13970         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13971         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13972         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13973         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13974         mContext.sendOrderedBroadcastAsUser(intent,
13975                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13976         */
13977         br.onReceive(mContext, intent);
13978     }
13979
13980     private long getLowRamTimeSinceIdle(long now) {
13981         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13982     }
13983
13984     @Override
13985     public void performIdleMaintenance() {
13986         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13987                 != PackageManager.PERMISSION_GRANTED) {
13988             throw new SecurityException("Requires permission "
13989                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13990         }
13991
13992         synchronized (this) {
13993             final long now = SystemClock.uptimeMillis();
13994             final long timeSinceLastIdle = now - mLastIdleTime;
13995             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13996             mLastIdleTime = now;
13997             mLowRamTimeSinceLastIdle = 0;
13998             if (mLowRamStartTime != 0) {
13999                 mLowRamStartTime = now;
14000             }
14001
14002             StringBuilder sb = new StringBuilder(128);
14003             sb.append("Idle maintenance over ");
14004             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14005             sb.append(" low RAM for ");
14006             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14007             Slog.i(TAG, sb.toString());
14008
14009             // If at least 1/3 of our time since the last idle period has been spent
14010             // with RAM low, then we want to kill processes.
14011             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14012
14013             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14014                 ProcessRecord proc = mLruProcesses.get(i);
14015                 if (proc.notCachedSinceIdle) {
14016                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14017                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14018                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14019                         if (doKilling && proc.initialIdlePss != 0
14020                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14021                             sb = new StringBuilder(128);
14022                             sb.append("Kill");
14023                             sb.append(proc.processName);
14024                             sb.append(" in idle maint: pss=");
14025                             sb.append(proc.lastPss);
14026                             sb.append(", swapPss=");
14027                             sb.append(proc.lastSwapPss);
14028                             sb.append(", initialPss=");
14029                             sb.append(proc.initialIdlePss);
14030                             sb.append(", period=");
14031                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14032                             sb.append(", lowRamPeriod=");
14033                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14034                             Slog.wtfQuiet(TAG, sb.toString());
14035                             proc.kill("idle maint (pss " + proc.lastPss
14036                                     + " from " + proc.initialIdlePss + ")", true);
14037                         }
14038                     }
14039                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14040                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14041                     proc.notCachedSinceIdle = true;
14042                     proc.initialIdlePss = 0;
14043                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14044                             mTestPssMode, isSleepingLocked(), now);
14045                 }
14046             }
14047
14048             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14049             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14050         }
14051     }
14052
14053     @Override
14054     public void sendIdleJobTrigger() {
14055         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14056                 != PackageManager.PERMISSION_GRANTED) {
14057             throw new SecurityException("Requires permission "
14058                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14059         }
14060
14061         final long ident = Binder.clearCallingIdentity();
14062         try {
14063             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14064                     .setPackage("android")
14065                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14066             broadcastIntent(null, intent, null, null, 0, null, null, null,
14067                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14068         } finally {
14069             Binder.restoreCallingIdentity(ident);
14070         }
14071     }
14072
14073     private void retrieveSettings() {
14074         final ContentResolver resolver = mContext.getContentResolver();
14075         final boolean freeformWindowManagement =
14076                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14077                         || Settings.Global.getInt(
14078                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14079
14080         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14081         final boolean supportsPictureInPicture = supportsMultiWindow &&
14082                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14083         final boolean supportsSplitScreenMultiWindow =
14084                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14085         final boolean supportsMultiDisplay = mContext.getPackageManager()
14086                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14087         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14088         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14089         final boolean alwaysFinishActivities =
14090                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14091         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14092         final boolean forceResizable = Settings.Global.getInt(
14093                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14094         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14095                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14096         final boolean supportsLeanbackOnly =
14097                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14098
14099         // Transfer any global setting for forcing RTL layout, into a System Property
14100         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14101
14102         final Configuration configuration = new Configuration();
14103         Settings.System.getConfiguration(resolver, configuration);
14104         if (forceRtl) {
14105             // This will take care of setting the correct layout direction flags
14106             configuration.setLayoutDirection(configuration.locale);
14107         }
14108
14109         synchronized (this) {
14110             mDebugApp = mOrigDebugApp = debugApp;
14111             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14112             mAlwaysFinishActivities = alwaysFinishActivities;
14113             mSupportsLeanbackOnly = supportsLeanbackOnly;
14114             mForceResizableActivities = forceResizable;
14115             final boolean multiWindowFormEnabled = freeformWindowManagement
14116                     || supportsSplitScreenMultiWindow
14117                     || supportsPictureInPicture
14118                     || supportsMultiDisplay;
14119             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14120                 mSupportsMultiWindow = true;
14121                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14122                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14123                 mSupportsPictureInPicture = supportsPictureInPicture;
14124                 mSupportsMultiDisplay = supportsMultiDisplay;
14125             } else {
14126                 mSupportsMultiWindow = false;
14127                 mSupportsFreeformWindowManagement = false;
14128                 mSupportsSplitScreenMultiWindow = false;
14129                 mSupportsPictureInPicture = false;
14130                 mSupportsMultiDisplay = false;
14131             }
14132             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14133             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14134             // This happens before any activities are started, so we can change global configuration
14135             // in-place.
14136             updateConfigurationLocked(configuration, null, true);
14137             final Configuration globalConfig = getGlobalConfiguration();
14138             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14139
14140             // Load resources only after the current configuration has been set.
14141             final Resources res = mContext.getResources();
14142             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14143             mThumbnailWidth = res.getDimensionPixelSize(
14144                     com.android.internal.R.dimen.thumbnail_width);
14145             mThumbnailHeight = res.getDimensionPixelSize(
14146                     com.android.internal.R.dimen.thumbnail_height);
14147             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14148                     com.android.internal.R.string.config_appsNotReportingCrashes));
14149             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14150                     com.android.internal.R.bool.config_customUserSwitchUi);
14151             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14152                 mFullscreenThumbnailScale = (float) res
14153                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14154                     (float) globalConfig.screenWidthDp;
14155             } else {
14156                 mFullscreenThumbnailScale = res.getFraction(
14157                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14158             }
14159             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14160         }
14161     }
14162
14163     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14164         traceLog.traceBegin("PhaseActivityManagerReady");
14165         synchronized(this) {
14166             if (mSystemReady) {
14167                 // If we're done calling all the receivers, run the next "boot phase" passed in
14168                 // by the SystemServer
14169                 if (goingCallback != null) {
14170                     goingCallback.run();
14171                 }
14172                 return;
14173             }
14174
14175             mLocalDeviceIdleController
14176                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14177             mAssistUtils = new AssistUtils(mContext);
14178             mVrController.onSystemReady();
14179             // Make sure we have the current profile info, since it is needed for security checks.
14180             mUserController.onSystemReady();
14181             mRecentTasks.onSystemReadyLocked();
14182             mAppOpsService.systemReady();
14183             mSystemReady = true;
14184         }
14185
14186         try {
14187             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14188                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14189                     .getSerial();
14190         } catch (RemoteException e) {}
14191
14192         ArrayList<ProcessRecord> procsToKill = null;
14193         synchronized(mPidsSelfLocked) {
14194             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14195                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14196                 if (!isAllowedWhileBooting(proc.info)){
14197                     if (procsToKill == null) {
14198                         procsToKill = new ArrayList<ProcessRecord>();
14199                     }
14200                     procsToKill.add(proc);
14201                 }
14202             }
14203         }
14204
14205         synchronized(this) {
14206             if (procsToKill != null) {
14207                 for (int i=procsToKill.size()-1; i>=0; i--) {
14208                     ProcessRecord proc = procsToKill.get(i);
14209                     Slog.i(TAG, "Removing system update proc: " + proc);
14210                     removeProcessLocked(proc, true, false, "system update done");
14211                 }
14212             }
14213
14214             // Now that we have cleaned up any update processes, we
14215             // are ready to start launching real processes and know that
14216             // we won't trample on them any more.
14217             mProcessesReady = true;
14218         }
14219
14220         Slog.i(TAG, "System now ready");
14221         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14222             SystemClock.uptimeMillis());
14223
14224         synchronized(this) {
14225             // Make sure we have no pre-ready processes sitting around.
14226
14227             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14228                 ResolveInfo ri = mContext.getPackageManager()
14229                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14230                                 STOCK_PM_FLAGS);
14231                 CharSequence errorMsg = null;
14232                 if (ri != null) {
14233                     ActivityInfo ai = ri.activityInfo;
14234                     ApplicationInfo app = ai.applicationInfo;
14235                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14236                         mTopAction = Intent.ACTION_FACTORY_TEST;
14237                         mTopData = null;
14238                         mTopComponent = new ComponentName(app.packageName,
14239                                 ai.name);
14240                     } else {
14241                         errorMsg = mContext.getResources().getText(
14242                                 com.android.internal.R.string.factorytest_not_system);
14243                     }
14244                 } else {
14245                     errorMsg = mContext.getResources().getText(
14246                             com.android.internal.R.string.factorytest_no_action);
14247                 }
14248                 if (errorMsg != null) {
14249                     mTopAction = null;
14250                     mTopData = null;
14251                     mTopComponent = null;
14252                     Message msg = Message.obtain();
14253                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14254                     msg.getData().putCharSequence("msg", errorMsg);
14255                     mUiHandler.sendMessage(msg);
14256                 }
14257             }
14258         }
14259
14260         retrieveSettings();
14261         final int currentUserId;
14262         synchronized (this) {
14263             currentUserId = mUserController.getCurrentUserIdLocked();
14264             readGrantedUriPermissionsLocked();
14265         }
14266
14267         if (goingCallback != null) goingCallback.run();
14268         traceLog.traceBegin("ActivityManagerStartApps");
14269         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14270                 Integer.toString(currentUserId), currentUserId);
14271         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14272                 Integer.toString(currentUserId), currentUserId);
14273         mSystemServiceManager.startUser(currentUserId);
14274
14275         synchronized (this) {
14276             // Only start up encryption-aware persistent apps; once user is
14277             // unlocked we'll come back around and start unaware apps
14278             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14279
14280             // Start up initial activity.
14281             mBooting = true;
14282             // Enable home activity for system user, so that the system can always boot. We don't
14283             // do this when the system user is not setup since the setup wizard should be the one
14284             // to handle home activity in this case.
14285             if (UserManager.isSplitSystemUser() &&
14286                     Settings.Secure.getInt(mContext.getContentResolver(),
14287                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14288                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14289                 try {
14290                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14291                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14292                             UserHandle.USER_SYSTEM);
14293                 } catch (RemoteException e) {
14294                     throw e.rethrowAsRuntimeException();
14295                 }
14296             }
14297             startHomeActivityLocked(currentUserId, "systemReady");
14298
14299             try {
14300                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14301                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14302                             + " data partition or your device will be unstable.");
14303                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14304                 }
14305             } catch (RemoteException e) {
14306             }
14307
14308             if (!Build.isBuildConsistent()) {
14309                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14310                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14311             }
14312
14313             long ident = Binder.clearCallingIdentity();
14314             try {
14315                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14316                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14317                         | Intent.FLAG_RECEIVER_FOREGROUND);
14318                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14319                 broadcastIntentLocked(null, null, intent,
14320                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14321                         null, false, false, MY_PID, SYSTEM_UID,
14322                         currentUserId);
14323                 intent = new Intent(Intent.ACTION_USER_STARTING);
14324                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14325                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14326                 broadcastIntentLocked(null, null, intent,
14327                         null, new IIntentReceiver.Stub() {
14328                             @Override
14329                             public void performReceive(Intent intent, int resultCode, String data,
14330                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14331                                     throws RemoteException {
14332                             }
14333                         }, 0, null, null,
14334                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14335                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14336             } catch (Throwable t) {
14337                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14338             } finally {
14339                 Binder.restoreCallingIdentity(ident);
14340             }
14341             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14342             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14343             traceLog.traceEnd(); // ActivityManagerStartApps
14344             traceLog.traceEnd(); // PhaseActivityManagerReady
14345         }
14346     }
14347
14348     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14349         synchronized (this) {
14350             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14351         }
14352     }
14353
14354     void skipCurrentReceiverLocked(ProcessRecord app) {
14355         for (BroadcastQueue queue : mBroadcastQueues) {
14356             queue.skipCurrentReceiverLocked(app);
14357         }
14358     }
14359
14360     /**
14361      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14362      * The application process will exit immediately after this call returns.
14363      * @param app object of the crashing app, null for the system server
14364      * @param crashInfo describing the exception
14365      */
14366     public void handleApplicationCrash(IBinder app,
14367             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14368         ProcessRecord r = findAppProcess(app, "Crash");
14369         final String processName = app == null ? "system_server"
14370                 : (r == null ? "unknown" : r.processName);
14371
14372         handleApplicationCrashInner("crash", r, processName, crashInfo);
14373     }
14374
14375     /* Native crash reporting uses this inner version because it needs to be somewhat
14376      * decoupled from the AM-managed cleanup lifecycle
14377      */
14378     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14379             ApplicationErrorReport.CrashInfo crashInfo) {
14380         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14381                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14382                 r == null ? -1 : r.info.flags,
14383                 crashInfo.exceptionClassName,
14384                 crashInfo.exceptionMessage,
14385                 crashInfo.throwFileName,
14386                 crashInfo.throwLineNumber);
14387
14388         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14389
14390         mAppErrors.crashApplication(r, crashInfo);
14391     }
14392
14393     public void handleApplicationStrictModeViolation(
14394             IBinder app,
14395             int violationMask,
14396             StrictMode.ViolationInfo info) {
14397         ProcessRecord r = findAppProcess(app, "StrictMode");
14398         if (r == null) {
14399             return;
14400         }
14401
14402         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14403             Integer stackFingerprint = info.hashCode();
14404             boolean logIt = true;
14405             synchronized (mAlreadyLoggedViolatedStacks) {
14406                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14407                     logIt = false;
14408                     // TODO: sub-sample into EventLog for these, with
14409                     // the info.durationMillis?  Then we'd get
14410                     // the relative pain numbers, without logging all
14411                     // the stack traces repeatedly.  We'd want to do
14412                     // likewise in the client code, which also does
14413                     // dup suppression, before the Binder call.
14414                 } else {
14415                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14416                         mAlreadyLoggedViolatedStacks.clear();
14417                     }
14418                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14419                 }
14420             }
14421             if (logIt) {
14422                 logStrictModeViolationToDropBox(r, info);
14423             }
14424         }
14425
14426         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14427             AppErrorResult result = new AppErrorResult();
14428             synchronized (this) {
14429                 final long origId = Binder.clearCallingIdentity();
14430
14431                 Message msg = Message.obtain();
14432                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14433                 HashMap<String, Object> data = new HashMap<String, Object>();
14434                 data.put("result", result);
14435                 data.put("app", r);
14436                 data.put("violationMask", violationMask);
14437                 data.put("info", info);
14438                 msg.obj = data;
14439                 mUiHandler.sendMessage(msg);
14440
14441                 Binder.restoreCallingIdentity(origId);
14442             }
14443             int res = result.get();
14444             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14445         }
14446     }
14447
14448     // Depending on the policy in effect, there could be a bunch of
14449     // these in quick succession so we try to batch these together to
14450     // minimize disk writes, number of dropbox entries, and maximize
14451     // compression, by having more fewer, larger records.
14452     private void logStrictModeViolationToDropBox(
14453             ProcessRecord process,
14454             StrictMode.ViolationInfo info) {
14455         if (info == null) {
14456             return;
14457         }
14458         final boolean isSystemApp = process == null ||
14459                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14460                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14461         final String processName = process == null ? "unknown" : process.processName;
14462         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14463         final DropBoxManager dbox = (DropBoxManager)
14464                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14465
14466         // Exit early if the dropbox isn't configured to accept this report type.
14467         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14468
14469         boolean bufferWasEmpty;
14470         boolean needsFlush;
14471         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14472         synchronized (sb) {
14473             bufferWasEmpty = sb.length() == 0;
14474             appendDropBoxProcessHeaders(process, processName, sb);
14475             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14476             sb.append("System-App: ").append(isSystemApp).append("\n");
14477             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14478             if (info.violationNumThisLoop != 0) {
14479                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14480             }
14481             if (info.numAnimationsRunning != 0) {
14482                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14483             }
14484             if (info.broadcastIntentAction != null) {
14485                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14486             }
14487             if (info.durationMillis != -1) {
14488                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14489             }
14490             if (info.numInstances != -1) {
14491                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14492             }
14493             if (info.tags != null) {
14494                 for (String tag : info.tags) {
14495                     sb.append("Span-Tag: ").append(tag).append("\n");
14496                 }
14497             }
14498             sb.append("\n");
14499             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14500                 sb.append(info.crashInfo.stackTrace);
14501                 sb.append("\n");
14502             }
14503             if (info.message != null) {
14504                 sb.append(info.message);
14505                 sb.append("\n");
14506             }
14507
14508             // Only buffer up to ~64k.  Various logging bits truncate
14509             // things at 128k.
14510             needsFlush = (sb.length() > 64 * 1024);
14511         }
14512
14513         // Flush immediately if the buffer's grown too large, or this
14514         // is a non-system app.  Non-system apps are isolated with a
14515         // different tag & policy and not batched.
14516         //
14517         // Batching is useful during internal testing with
14518         // StrictMode settings turned up high.  Without batching,
14519         // thousands of separate files could be created on boot.
14520         if (!isSystemApp || needsFlush) {
14521             new Thread("Error dump: " + dropboxTag) {
14522                 @Override
14523                 public void run() {
14524                     String report;
14525                     synchronized (sb) {
14526                         report = sb.toString();
14527                         sb.delete(0, sb.length());
14528                         sb.trimToSize();
14529                     }
14530                     if (report.length() != 0) {
14531                         dbox.addText(dropboxTag, report);
14532                     }
14533                 }
14534             }.start();
14535             return;
14536         }
14537
14538         // System app batching:
14539         if (!bufferWasEmpty) {
14540             // An existing dropbox-writing thread is outstanding, so
14541             // we don't need to start it up.  The existing thread will
14542             // catch the buffer appends we just did.
14543             return;
14544         }
14545
14546         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14547         // (After this point, we shouldn't access AMS internal data structures.)
14548         new Thread("Error dump: " + dropboxTag) {
14549             @Override
14550             public void run() {
14551                 // 5 second sleep to let stacks arrive and be batched together
14552                 try {
14553                     Thread.sleep(5000);  // 5 seconds
14554                 } catch (InterruptedException e) {}
14555
14556                 String errorReport;
14557                 synchronized (mStrictModeBuffer) {
14558                     errorReport = mStrictModeBuffer.toString();
14559                     if (errorReport.length() == 0) {
14560                         return;
14561                     }
14562                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14563                     mStrictModeBuffer.trimToSize();
14564                 }
14565                 dbox.addText(dropboxTag, errorReport);
14566             }
14567         }.start();
14568     }
14569
14570     /**
14571      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14572      * @param app object of the crashing app, null for the system server
14573      * @param tag reported by the caller
14574      * @param system whether this wtf is coming from the system
14575      * @param crashInfo describing the context of the error
14576      * @return true if the process should exit immediately (WTF is fatal)
14577      */
14578     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14579             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14580         final int callingUid = Binder.getCallingUid();
14581         final int callingPid = Binder.getCallingPid();
14582
14583         if (system) {
14584             // If this is coming from the system, we could very well have low-level
14585             // system locks held, so we want to do this all asynchronously.  And we
14586             // never want this to become fatal, so there is that too.
14587             mHandler.post(new Runnable() {
14588                 @Override public void run() {
14589                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14590                 }
14591             });
14592             return false;
14593         }
14594
14595         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14596                 crashInfo);
14597
14598         final boolean isFatal = Build.IS_ENG || Settings.Global
14599                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14600         final boolean isSystem = (r == null) || r.persistent;
14601
14602         if (isFatal && !isSystem) {
14603             mAppErrors.crashApplication(r, crashInfo);
14604             return true;
14605         } else {
14606             return false;
14607         }
14608     }
14609
14610     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14611             final ApplicationErrorReport.CrashInfo crashInfo) {
14612         final ProcessRecord r = findAppProcess(app, "WTF");
14613         final String processName = app == null ? "system_server"
14614                 : (r == null ? "unknown" : r.processName);
14615
14616         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14617                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14618
14619         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14620
14621         return r;
14622     }
14623
14624     /**
14625      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14626      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14627      */
14628     private ProcessRecord findAppProcess(IBinder app, String reason) {
14629         if (app == null) {
14630             return null;
14631         }
14632
14633         synchronized (this) {
14634             final int NP = mProcessNames.getMap().size();
14635             for (int ip=0; ip<NP; ip++) {
14636                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14637                 final int NA = apps.size();
14638                 for (int ia=0; ia<NA; ia++) {
14639                     ProcessRecord p = apps.valueAt(ia);
14640                     if (p.thread != null && p.thread.asBinder() == app) {
14641                         return p;
14642                     }
14643                 }
14644             }
14645
14646             Slog.w(TAG, "Can't find mystery application for " + reason
14647                     + " from pid=" + Binder.getCallingPid()
14648                     + " uid=" + Binder.getCallingUid() + ": " + app);
14649             return null;
14650         }
14651     }
14652
14653     /**
14654      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14655      * to append various headers to the dropbox log text.
14656      */
14657     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14658             StringBuilder sb) {
14659         // Watchdog thread ends up invoking this function (with
14660         // a null ProcessRecord) to add the stack file to dropbox.
14661         // Do not acquire a lock on this (am) in such cases, as it
14662         // could cause a potential deadlock, if and when watchdog
14663         // is invoked due to unavailability of lock on am and it
14664         // would prevent watchdog from killing system_server.
14665         if (process == null) {
14666             sb.append("Process: ").append(processName).append("\n");
14667             return;
14668         }
14669         // Note: ProcessRecord 'process' is guarded by the service
14670         // instance.  (notably process.pkgList, which could otherwise change
14671         // concurrently during execution of this method)
14672         synchronized (this) {
14673             sb.append("Process: ").append(processName).append("\n");
14674             sb.append("PID: ").append(process.pid).append("\n");
14675             int flags = process.info.flags;
14676             IPackageManager pm = AppGlobals.getPackageManager();
14677             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14678             for (int ip=0; ip<process.pkgList.size(); ip++) {
14679                 String pkg = process.pkgList.keyAt(ip);
14680                 sb.append("Package: ").append(pkg);
14681                 try {
14682                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14683                     if (pi != null) {
14684                         sb.append(" v").append(pi.versionCode);
14685                         if (pi.versionName != null) {
14686                             sb.append(" (").append(pi.versionName).append(")");
14687                         }
14688                     }
14689                 } catch (RemoteException e) {
14690                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14691                 }
14692                 sb.append("\n");
14693             }
14694             if (process.info.isInstantApp()) {
14695                 sb.append("Instant-App: true\n");
14696             }
14697         }
14698     }
14699
14700     private static String processClass(ProcessRecord process) {
14701         if (process == null || process.pid == MY_PID) {
14702             return "system_server";
14703         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14704             return "system_app";
14705         } else {
14706             return "data_app";
14707         }
14708     }
14709
14710     private volatile long mWtfClusterStart;
14711     private volatile int mWtfClusterCount;
14712
14713     /**
14714      * Write a description of an error (crash, WTF, ANR) to the drop box.
14715      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14716      * @param process which caused the error, null means the system server
14717      * @param activity which triggered the error, null if unknown
14718      * @param parent activity related to the error, null if unknown
14719      * @param subject line related to the error, null if absent
14720      * @param report in long form describing the error, null if absent
14721      * @param dataFile text file to include in the report, null if none
14722      * @param crashInfo giving an application stack trace, null if absent
14723      */
14724     public void addErrorToDropBox(String eventType,
14725             ProcessRecord process, String processName, ActivityRecord activity,
14726             ActivityRecord parent, String subject,
14727             final String report, final File dataFile,
14728             final ApplicationErrorReport.CrashInfo crashInfo) {
14729         // NOTE -- this must never acquire the ActivityManagerService lock,
14730         // otherwise the watchdog may be prevented from resetting the system.
14731
14732         // Bail early if not published yet
14733         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14734         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14735
14736         // Exit early if the dropbox isn't configured to accept this report type.
14737         final String dropboxTag = processClass(process) + "_" + eventType;
14738         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14739
14740         // Rate-limit how often we're willing to do the heavy lifting below to
14741         // collect and record logs; currently 5 logs per 10 second period.
14742         final long now = SystemClock.elapsedRealtime();
14743         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14744             mWtfClusterStart = now;
14745             mWtfClusterCount = 1;
14746         } else {
14747             if (mWtfClusterCount++ >= 5) return;
14748         }
14749
14750         final StringBuilder sb = new StringBuilder(1024);
14751         appendDropBoxProcessHeaders(process, processName, sb);
14752         if (process != null) {
14753             sb.append("Foreground: ")
14754                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14755                     .append("\n");
14756         }
14757         if (activity != null) {
14758             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14759         }
14760         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14761             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14762         }
14763         if (parent != null && parent != activity) {
14764             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14765         }
14766         if (subject != null) {
14767             sb.append("Subject: ").append(subject).append("\n");
14768         }
14769         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14770         if (Debug.isDebuggerConnected()) {
14771             sb.append("Debugger: Connected\n");
14772         }
14773         sb.append("\n");
14774
14775         // Do the rest in a worker thread to avoid blocking the caller on I/O
14776         // (After this point, we shouldn't access AMS internal data structures.)
14777         Thread worker = new Thread("Error dump: " + dropboxTag) {
14778             @Override
14779             public void run() {
14780                 if (report != null) {
14781                     sb.append(report);
14782                 }
14783
14784                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14785                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14786                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14787                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14788
14789                 if (dataFile != null && maxDataFileSize > 0) {
14790                     try {
14791                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14792                                     "\n\n[[TRUNCATED]]"));
14793                     } catch (IOException e) {
14794                         Slog.e(TAG, "Error reading " + dataFile, e);
14795                     }
14796                 }
14797                 if (crashInfo != null && crashInfo.stackTrace != null) {
14798                     sb.append(crashInfo.stackTrace);
14799                 }
14800
14801                 if (lines > 0) {
14802                     sb.append("\n");
14803
14804                     // Merge several logcat streams, and take the last N lines
14805                     InputStreamReader input = null;
14806                     try {
14807                         java.lang.Process logcat = new ProcessBuilder(
14808                                 "/system/bin/timeout", "-k", "15s", "10s",
14809                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14810                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14811                                         .redirectErrorStream(true).start();
14812
14813                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14814                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14815                         input = new InputStreamReader(logcat.getInputStream());
14816
14817                         int num;
14818                         char[] buf = new char[8192];
14819                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14820                     } catch (IOException e) {
14821                         Slog.e(TAG, "Error running logcat", e);
14822                     } finally {
14823                         if (input != null) try { input.close(); } catch (IOException e) {}
14824                     }
14825                 }
14826
14827                 dbox.addText(dropboxTag, sb.toString());
14828             }
14829         };
14830
14831         if (process == null) {
14832             // If process is null, we are being called from some internal code
14833             // and may be about to die -- run this synchronously.
14834             worker.run();
14835         } else {
14836             worker.start();
14837         }
14838     }
14839
14840     @Override
14841     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14842         enforceNotIsolatedCaller("getProcessesInErrorState");
14843         // assume our apps are happy - lazy create the list
14844         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14845
14846         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14847                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14848         int userId = UserHandle.getUserId(Binder.getCallingUid());
14849
14850         synchronized (this) {
14851
14852             // iterate across all processes
14853             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14854                 ProcessRecord app = mLruProcesses.get(i);
14855                 if (!allUsers && app.userId != userId) {
14856                     continue;
14857                 }
14858                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14859                     // This one's in trouble, so we'll generate a report for it
14860                     // crashes are higher priority (in case there's a crash *and* an anr)
14861                     ActivityManager.ProcessErrorStateInfo report = null;
14862                     if (app.crashing) {
14863                         report = app.crashingReport;
14864                     } else if (app.notResponding) {
14865                         report = app.notRespondingReport;
14866                     }
14867
14868                     if (report != null) {
14869                         if (errList == null) {
14870                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14871                         }
14872                         errList.add(report);
14873                     } else {
14874                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14875                                 " crashing = " + app.crashing +
14876                                 " notResponding = " + app.notResponding);
14877                     }
14878                 }
14879             }
14880         }
14881
14882         return errList;
14883     }
14884
14885     static int procStateToImportance(int procState, int memAdj,
14886             ActivityManager.RunningAppProcessInfo currApp,
14887             int clientTargetSdk) {
14888         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14889                 procState, clientTargetSdk);
14890         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14891             currApp.lru = memAdj;
14892         } else {
14893             currApp.lru = 0;
14894         }
14895         return imp;
14896     }
14897
14898     private void fillInProcMemInfo(ProcessRecord app,
14899             ActivityManager.RunningAppProcessInfo outInfo,
14900             int clientTargetSdk) {
14901         outInfo.pid = app.pid;
14902         outInfo.uid = app.info.uid;
14903         if (mHeavyWeightProcess == app) {
14904             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14905         }
14906         if (app.persistent) {
14907             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14908         }
14909         if (app.activities.size() > 0) {
14910             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14911         }
14912         outInfo.lastTrimLevel = app.trimMemoryLevel;
14913         int adj = app.curAdj;
14914         int procState = app.curProcState;
14915         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14916         outInfo.importanceReasonCode = app.adjTypeCode;
14917         outInfo.processState = app.curProcState;
14918     }
14919
14920     @Override
14921     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14922         enforceNotIsolatedCaller("getRunningAppProcesses");
14923
14924         final int callingUid = Binder.getCallingUid();
14925         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14926
14927         // Lazy instantiation of list
14928         List<ActivityManager.RunningAppProcessInfo> runList = null;
14929         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14930                 callingUid) == PackageManager.PERMISSION_GRANTED;
14931         final int userId = UserHandle.getUserId(callingUid);
14932         final boolean allUids = isGetTasksAllowed(
14933                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14934
14935         synchronized (this) {
14936             // Iterate across all processes
14937             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14938                 ProcessRecord app = mLruProcesses.get(i);
14939                 if ((!allUsers && app.userId != userId)
14940                         || (!allUids && app.uid != callingUid)) {
14941                     continue;
14942                 }
14943                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14944                     // Generate process state info for running application
14945                     ActivityManager.RunningAppProcessInfo currApp =
14946                         new ActivityManager.RunningAppProcessInfo(app.processName,
14947                                 app.pid, app.getPackageList());
14948                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14949                     if (app.adjSource instanceof ProcessRecord) {
14950                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14951                         currApp.importanceReasonImportance =
14952                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14953                                         app.adjSourceProcState);
14954                     } else if (app.adjSource instanceof ActivityRecord) {
14955                         ActivityRecord r = (ActivityRecord)app.adjSource;
14956                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14957                     }
14958                     if (app.adjTarget instanceof ComponentName) {
14959                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14960                     }
14961                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14962                     //        + " lru=" + currApp.lru);
14963                     if (runList == null) {
14964                         runList = new ArrayList<>();
14965                     }
14966                     runList.add(currApp);
14967                 }
14968             }
14969         }
14970         return runList;
14971     }
14972
14973     @Override
14974     public List<ApplicationInfo> getRunningExternalApplications() {
14975         enforceNotIsolatedCaller("getRunningExternalApplications");
14976         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14977         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14978         if (runningApps != null && runningApps.size() > 0) {
14979             Set<String> extList = new HashSet<String>();
14980             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14981                 if (app.pkgList != null) {
14982                     for (String pkg : app.pkgList) {
14983                         extList.add(pkg);
14984                     }
14985                 }
14986             }
14987             IPackageManager pm = AppGlobals.getPackageManager();
14988             for (String pkg : extList) {
14989                 try {
14990                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14991                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14992                         retList.add(info);
14993                     }
14994                 } catch (RemoteException e) {
14995                 }
14996             }
14997         }
14998         return retList;
14999     }
15000
15001     @Override
15002     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15003         enforceNotIsolatedCaller("getMyMemoryState");
15004
15005         final int callingUid = Binder.getCallingUid();
15006         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15007
15008         synchronized (this) {
15009             ProcessRecord proc;
15010             synchronized (mPidsSelfLocked) {
15011                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15012             }
15013             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15014         }
15015     }
15016
15017     @Override
15018     public int getMemoryTrimLevel() {
15019         enforceNotIsolatedCaller("getMyMemoryState");
15020         synchronized (this) {
15021             return mLastMemoryLevel;
15022         }
15023     }
15024
15025     @Override
15026     public void onShellCommand(FileDescriptor in, FileDescriptor out,
15027             FileDescriptor err, String[] args, ShellCallback callback,
15028             ResultReceiver resultReceiver) {
15029         (new ActivityManagerShellCommand(this, false)).exec(
15030                 this, in, out, err, args, callback, resultReceiver);
15031     }
15032
15033     SleepToken acquireSleepToken(String tag, int displayId) {
15034         synchronized (this) {
15035             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15036             updateSleepIfNeededLocked();
15037             return token;
15038         }
15039     }
15040
15041     @Override
15042     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15043         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15044
15045         boolean dumpAll = false;
15046         boolean dumpClient = false;
15047         boolean dumpCheckin = false;
15048         boolean dumpCheckinFormat = false;
15049         boolean dumpVisibleStacksOnly = false;
15050         boolean dumpFocusedStackOnly = false;
15051         String dumpPackage = null;
15052
15053         int opti = 0;
15054         while (opti < args.length) {
15055             String opt = args[opti];
15056             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15057                 break;
15058             }
15059             opti++;
15060             if ("-a".equals(opt)) {
15061                 dumpAll = true;
15062             } else if ("-c".equals(opt)) {
15063                 dumpClient = true;
15064             } else if ("-v".equals(opt)) {
15065                 dumpVisibleStacksOnly = true;
15066             } else if ("-f".equals(opt)) {
15067                 dumpFocusedStackOnly = true;
15068             } else if ("-p".equals(opt)) {
15069                 if (opti < args.length) {
15070                     dumpPackage = args[opti];
15071                     opti++;
15072                 } else {
15073                     pw.println("Error: -p option requires package argument");
15074                     return;
15075                 }
15076                 dumpClient = true;
15077             } else if ("--checkin".equals(opt)) {
15078                 dumpCheckin = dumpCheckinFormat = true;
15079             } else if ("-C".equals(opt)) {
15080                 dumpCheckinFormat = true;
15081             } else if ("-h".equals(opt)) {
15082                 ActivityManagerShellCommand.dumpHelp(pw, true);
15083                 return;
15084             } else {
15085                 pw.println("Unknown argument: " + opt + "; use -h for help");
15086             }
15087         }
15088
15089         long origId = Binder.clearCallingIdentity();
15090         boolean more = false;
15091         // Is the caller requesting to dump a particular piece of data?
15092         if (opti < args.length) {
15093             String cmd = args[opti];
15094             opti++;
15095             if ("activities".equals(cmd) || "a".equals(cmd)) {
15096                 synchronized (this) {
15097                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15098                 }
15099             } else if ("lastanr".equals(cmd)) {
15100                 synchronized (this) {
15101                     dumpLastANRLocked(pw);
15102                 }
15103             } else if ("starter".equals(cmd)) {
15104                 synchronized (this) {
15105                     dumpActivityStarterLocked(pw, dumpPackage);
15106                 }
15107             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15108                 synchronized (this) {
15109                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15110                 }
15111             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15112                 String[] newArgs;
15113                 String name;
15114                 if (opti >= args.length) {
15115                     name = null;
15116                     newArgs = EMPTY_STRING_ARRAY;
15117                 } else {
15118                     dumpPackage = args[opti];
15119                     opti++;
15120                     newArgs = new String[args.length - opti];
15121                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15122                             args.length - opti);
15123                 }
15124                 synchronized (this) {
15125                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15126                 }
15127             } else if ("broadcast-stats".equals(cmd)) {
15128                 String[] newArgs;
15129                 String name;
15130                 if (opti >= args.length) {
15131                     name = null;
15132                     newArgs = EMPTY_STRING_ARRAY;
15133                 } else {
15134                     dumpPackage = args[opti];
15135                     opti++;
15136                     newArgs = new String[args.length - opti];
15137                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15138                             args.length - opti);
15139                 }
15140                 synchronized (this) {
15141                     if (dumpCheckinFormat) {
15142                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15143                                 dumpPackage);
15144                     } else {
15145                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15146                     }
15147                 }
15148             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15149                 String[] newArgs;
15150                 String name;
15151                 if (opti >= args.length) {
15152                     name = null;
15153                     newArgs = EMPTY_STRING_ARRAY;
15154                 } else {
15155                     dumpPackage = args[opti];
15156                     opti++;
15157                     newArgs = new String[args.length - opti];
15158                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15159                             args.length - opti);
15160                 }
15161                 synchronized (this) {
15162                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15163                 }
15164             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15165                 String[] newArgs;
15166                 String name;
15167                 if (opti >= args.length) {
15168                     name = null;
15169                     newArgs = EMPTY_STRING_ARRAY;
15170                 } else {
15171                     dumpPackage = args[opti];
15172                     opti++;
15173                     newArgs = new String[args.length - opti];
15174                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15175                             args.length - opti);
15176                 }
15177                 synchronized (this) {
15178                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15179                 }
15180             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15181                 synchronized (this) {
15182                     dumpOomLocked(fd, pw, args, opti, true);
15183                 }
15184             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15185                 synchronized (this) {
15186                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15187                 }
15188             } else if ("provider".equals(cmd)) {
15189                 String[] newArgs;
15190                 String name;
15191                 if (opti >= args.length) {
15192                     name = null;
15193                     newArgs = EMPTY_STRING_ARRAY;
15194                 } else {
15195                     name = args[opti];
15196                     opti++;
15197                     newArgs = new String[args.length - opti];
15198                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15199                 }
15200                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15201                     pw.println("No providers match: " + name);
15202                     pw.println("Use -h for help.");
15203                 }
15204             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15205                 synchronized (this) {
15206                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15207                 }
15208             } else if ("service".equals(cmd)) {
15209                 String[] newArgs;
15210                 String name;
15211                 if (opti >= args.length) {
15212                     name = null;
15213                     newArgs = EMPTY_STRING_ARRAY;
15214                 } else {
15215                     name = args[opti];
15216                     opti++;
15217                     newArgs = new String[args.length - opti];
15218                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15219                             args.length - opti);
15220                 }
15221                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15222                     pw.println("No services match: " + name);
15223                     pw.println("Use -h for help.");
15224                 }
15225             } else if ("package".equals(cmd)) {
15226                 String[] newArgs;
15227                 if (opti >= args.length) {
15228                     pw.println("package: no package name specified");
15229                     pw.println("Use -h for help.");
15230                 } else {
15231                     dumpPackage = args[opti];
15232                     opti++;
15233                     newArgs = new String[args.length - opti];
15234                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15235                             args.length - opti);
15236                     args = newArgs;
15237                     opti = 0;
15238                     more = true;
15239                 }
15240             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15241                 synchronized (this) {
15242                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15243                 }
15244             } else if ("settings".equals(cmd)) {
15245                 synchronized (this) {
15246                     mConstants.dump(pw);
15247                 }
15248             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15249                 if (dumpClient) {
15250                     ActiveServices.ServiceDumper dumper;
15251                     synchronized (this) {
15252                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15253                                 dumpPackage);
15254                     }
15255                     dumper.dumpWithClient();
15256                 } else {
15257                     synchronized (this) {
15258                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15259                                 dumpPackage).dumpLocked();
15260                     }
15261                 }
15262             } else if ("locks".equals(cmd)) {
15263                 LockGuard.dump(fd, pw, args);
15264             } else {
15265                 // Dumping a single activity?
15266                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15267                         dumpFocusedStackOnly)) {
15268                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15269                     int res = shell.exec(this, null, fd, null, args, null,
15270                             new ResultReceiver(null));
15271                     if (res < 0) {
15272                         pw.println("Bad activity command, or no activities match: " + cmd);
15273                         pw.println("Use -h for help.");
15274                     }
15275                 }
15276             }
15277             if (!more) {
15278                 Binder.restoreCallingIdentity(origId);
15279                 return;
15280             }
15281         }
15282
15283         // No piece of data specified, dump everything.
15284         if (dumpCheckinFormat) {
15285             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15286         } else if (dumpClient) {
15287             ActiveServices.ServiceDumper sdumper;
15288             synchronized (this) {
15289                 mConstants.dump(pw);
15290                 pw.println();
15291                 if (dumpAll) {
15292                     pw.println("-------------------------------------------------------------------------------");
15293                 }
15294                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15295                 pw.println();
15296                 if (dumpAll) {
15297                     pw.println("-------------------------------------------------------------------------------");
15298                 }
15299                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15300                 pw.println();
15301                 if (dumpAll) {
15302                     pw.println("-------------------------------------------------------------------------------");
15303                 }
15304                 if (dumpAll || dumpPackage != null) {
15305                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15306                     pw.println();
15307                     if (dumpAll) {
15308                         pw.println("-------------------------------------------------------------------------------");
15309                     }
15310                 }
15311                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15312                 pw.println();
15313                 if (dumpAll) {
15314                     pw.println("-------------------------------------------------------------------------------");
15315                 }
15316                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15317                 pw.println();
15318                 if (dumpAll) {
15319                     pw.println("-------------------------------------------------------------------------------");
15320                 }
15321                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15322                         dumpPackage);
15323             }
15324             sdumper.dumpWithClient();
15325             pw.println();
15326             synchronized (this) {
15327                 if (dumpAll) {
15328                     pw.println("-------------------------------------------------------------------------------");
15329                 }
15330                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15331                 pw.println();
15332                 if (dumpAll) {
15333                     pw.println("-------------------------------------------------------------------------------");
15334                 }
15335                 dumpLastANRLocked(pw);
15336                 pw.println();
15337                 if (dumpAll) {
15338                     pw.println("-------------------------------------------------------------------------------");
15339                 }
15340                 dumpActivityStarterLocked(pw, dumpPackage);
15341                 pw.println();
15342                 if (dumpAll) {
15343                     pw.println("-------------------------------------------------------------------------------");
15344                 }
15345                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15346                 if (mAssociations.size() > 0) {
15347                     pw.println();
15348                     if (dumpAll) {
15349                         pw.println("-------------------------------------------------------------------------------");
15350                     }
15351                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15352                 }
15353                 pw.println();
15354                 if (dumpAll) {
15355                     pw.println("-------------------------------------------------------------------------------");
15356                 }
15357                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15358             }
15359
15360         } else {
15361             synchronized (this) {
15362                 mConstants.dump(pw);
15363                 pw.println();
15364                 if (dumpAll) {
15365                     pw.println("-------------------------------------------------------------------------------");
15366                 }
15367                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15368                 pw.println();
15369                 if (dumpAll) {
15370                     pw.println("-------------------------------------------------------------------------------");
15371                 }
15372                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15373                 pw.println();
15374                 if (dumpAll) {
15375                     pw.println("-------------------------------------------------------------------------------");
15376                 }
15377                 if (dumpAll || dumpPackage != null) {
15378                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15379                     pw.println();
15380                     if (dumpAll) {
15381                         pw.println("-------------------------------------------------------------------------------");
15382                     }
15383                 }
15384                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15385                 pw.println();
15386                 if (dumpAll) {
15387                     pw.println("-------------------------------------------------------------------------------");
15388                 }
15389                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15390                 pw.println();
15391                 if (dumpAll) {
15392                     pw.println("-------------------------------------------------------------------------------");
15393                 }
15394                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15395                         .dumpLocked();
15396                 pw.println();
15397                 if (dumpAll) {
15398                     pw.println("-------------------------------------------------------------------------------");
15399                 }
15400                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15401                 pw.println();
15402                 if (dumpAll) {
15403                     pw.println("-------------------------------------------------------------------------------");
15404                 }
15405                 dumpLastANRLocked(pw);
15406                 pw.println();
15407                 if (dumpAll) {
15408                     pw.println("-------------------------------------------------------------------------------");
15409                 }
15410                 dumpActivityStarterLocked(pw, dumpPackage);
15411                 pw.println();
15412                 if (dumpAll) {
15413                     pw.println("-------------------------------------------------------------------------------");
15414                 }
15415                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15416                 if (mAssociations.size() > 0) {
15417                     pw.println();
15418                     if (dumpAll) {
15419                         pw.println("-------------------------------------------------------------------------------");
15420                     }
15421                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15422                 }
15423                 pw.println();
15424                 if (dumpAll) {
15425                     pw.println("-------------------------------------------------------------------------------");
15426                 }
15427                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15428             }
15429         }
15430         Binder.restoreCallingIdentity(origId);
15431     }
15432
15433     private void dumpLastANRLocked(PrintWriter pw) {
15434         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15435         if (mLastANRState == null) {
15436             pw.println("  <no ANR has occurred since boot>");
15437         } else {
15438             pw.println(mLastANRState);
15439         }
15440     }
15441
15442     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15443         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15444         mActivityStarter.dump(pw, "", dumpPackage);
15445     }
15446
15447     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15448             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15449         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15450                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15451     }
15452
15453     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15454             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15455         pw.println(header);
15456
15457         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15458                 dumpPackage);
15459         boolean needSep = printedAnything;
15460
15461         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15462                 mStackSupervisor.getResumedActivityLocked(),
15463                 dumpPackage, needSep, "  ResumedActivity: ");
15464         if (printed) {
15465             printedAnything = true;
15466             needSep = false;
15467         }
15468
15469         if (dumpPackage == null) {
15470             if (needSep) {
15471                 pw.println();
15472             }
15473             printedAnything = true;
15474             mStackSupervisor.dump(pw, "  ");
15475         }
15476
15477         if (!printedAnything) {
15478             pw.println("  (nothing)");
15479         }
15480     }
15481
15482     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15483             int opti, boolean dumpAll, String dumpPackage) {
15484         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15485
15486         boolean printedAnything = false;
15487
15488         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15489             boolean printedHeader = false;
15490
15491             final int N = mRecentTasks.size();
15492             for (int i=0; i<N; i++) {
15493                 TaskRecord tr = mRecentTasks.get(i);
15494                 if (dumpPackage != null) {
15495                     if (tr.realActivity == null ||
15496                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15497                         continue;
15498                     }
15499                 }
15500                 if (!printedHeader) {
15501                     pw.println("  Recent tasks:");
15502                     printedHeader = true;
15503                     printedAnything = true;
15504                 }
15505                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15506                         pw.println(tr);
15507                 if (dumpAll) {
15508                     mRecentTasks.get(i).dump(pw, "    ");
15509                 }
15510             }
15511         }
15512
15513         if (!printedAnything) {
15514             pw.println("  (nothing)");
15515         }
15516     }
15517
15518     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15519             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15520         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15521
15522         int dumpUid = 0;
15523         if (dumpPackage != null) {
15524             IPackageManager pm = AppGlobals.getPackageManager();
15525             try {
15526                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15527             } catch (RemoteException e) {
15528             }
15529         }
15530
15531         boolean printedAnything = false;
15532
15533         final long now = SystemClock.uptimeMillis();
15534
15535         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15536             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15537                     = mAssociations.valueAt(i1);
15538             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15539                 SparseArray<ArrayMap<String, Association>> sourceUids
15540                         = targetComponents.valueAt(i2);
15541                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15542                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15543                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15544                         Association ass = sourceProcesses.valueAt(i4);
15545                         if (dumpPackage != null) {
15546                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15547                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15548                                 continue;
15549                             }
15550                         }
15551                         printedAnything = true;
15552                         pw.print("  ");
15553                         pw.print(ass.mTargetProcess);
15554                         pw.print("/");
15555                         UserHandle.formatUid(pw, ass.mTargetUid);
15556                         pw.print(" <- ");
15557                         pw.print(ass.mSourceProcess);
15558                         pw.print("/");
15559                         UserHandle.formatUid(pw, ass.mSourceUid);
15560                         pw.println();
15561                         pw.print("    via ");
15562                         pw.print(ass.mTargetComponent.flattenToShortString());
15563                         pw.println();
15564                         pw.print("    ");
15565                         long dur = ass.mTime;
15566                         if (ass.mNesting > 0) {
15567                             dur += now - ass.mStartTime;
15568                         }
15569                         TimeUtils.formatDuration(dur, pw);
15570                         pw.print(" (");
15571                         pw.print(ass.mCount);
15572                         pw.print(" times)");
15573                         pw.print("  ");
15574                         for (int i=0; i<ass.mStateTimes.length; i++) {
15575                             long amt = ass.mStateTimes[i];
15576                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15577                                 amt += now - ass.mLastStateUptime;
15578                             }
15579                             if (amt != 0) {
15580                                 pw.print(" ");
15581                                 pw.print(ProcessList.makeProcStateString(
15582                                             i + ActivityManager.MIN_PROCESS_STATE));
15583                                 pw.print("=");
15584                                 TimeUtils.formatDuration(amt, pw);
15585                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15586                                     pw.print("*");
15587                                 }
15588                             }
15589                         }
15590                         pw.println();
15591                         if (ass.mNesting > 0) {
15592                             pw.print("    Currently active: ");
15593                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15594                             pw.println();
15595                         }
15596                     }
15597                 }
15598             }
15599
15600         }
15601
15602         if (!printedAnything) {
15603             pw.println("  (nothing)");
15604         }
15605     }
15606
15607     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15608             String header, boolean needSep) {
15609         boolean printed = false;
15610         int whichAppId = -1;
15611         if (dumpPackage != null) {
15612             try {
15613                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15614                         dumpPackage, 0);
15615                 whichAppId = UserHandle.getAppId(info.uid);
15616             } catch (NameNotFoundException e) {
15617                 e.printStackTrace();
15618             }
15619         }
15620         for (int i=0; i<uids.size(); i++) {
15621             UidRecord uidRec = uids.valueAt(i);
15622             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15623                 continue;
15624             }
15625             if (!printed) {
15626                 printed = true;
15627                 if (needSep) {
15628                     pw.println();
15629                 }
15630                 pw.print("  ");
15631                 pw.println(header);
15632                 needSep = true;
15633             }
15634             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15635             pw.print(": "); pw.println(uidRec);
15636         }
15637         return printed;
15638     }
15639
15640     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15641             int opti, boolean dumpAll, String dumpPackage) {
15642         boolean needSep = false;
15643         boolean printedAnything = false;
15644         int numPers = 0;
15645
15646         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15647
15648         if (dumpAll) {
15649             final int NP = mProcessNames.getMap().size();
15650             for (int ip=0; ip<NP; ip++) {
15651                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15652                 final int NA = procs.size();
15653                 for (int ia=0; ia<NA; ia++) {
15654                     ProcessRecord r = procs.valueAt(ia);
15655                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15656                         continue;
15657                     }
15658                     if (!needSep) {
15659                         pw.println("  All known processes:");
15660                         needSep = true;
15661                         printedAnything = true;
15662                     }
15663                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15664                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15665                         pw.print(" "); pw.println(r);
15666                     r.dump(pw, "    ");
15667                     if (r.persistent) {
15668                         numPers++;
15669                     }
15670                 }
15671             }
15672         }
15673
15674         if (mIsolatedProcesses.size() > 0) {
15675             boolean printed = false;
15676             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15677                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15678                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15679                     continue;
15680                 }
15681                 if (!printed) {
15682                     if (needSep) {
15683                         pw.println();
15684                     }
15685                     pw.println("  Isolated process list (sorted by uid):");
15686                     printedAnything = true;
15687                     printed = true;
15688                     needSep = true;
15689                 }
15690                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15691                 pw.println(r);
15692             }
15693         }
15694
15695         if (mActiveInstrumentation.size() > 0) {
15696             boolean printed = false;
15697             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15698                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15699                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15700                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15701                     continue;
15702                 }
15703                 if (!printed) {
15704                     if (needSep) {
15705                         pw.println();
15706                     }
15707                     pw.println("  Active instrumentation:");
15708                     printedAnything = true;
15709                     printed = true;
15710                     needSep = true;
15711                 }
15712                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15713                 pw.println(ai);
15714                 ai.dump(pw, "      ");
15715             }
15716         }
15717
15718         if (mActiveUids.size() > 0) {
15719             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15720                 printedAnything = needSep = true;
15721             }
15722         }
15723         if (dumpAll) {
15724             if (mValidateUids.size() > 0) {
15725                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15726                     printedAnything = needSep = true;
15727                 }
15728             }
15729         }
15730
15731         if (mLruProcesses.size() > 0) {
15732             if (needSep) {
15733                 pw.println();
15734             }
15735             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15736                     pw.print(" total, non-act at ");
15737                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15738                     pw.print(", non-svc at ");
15739                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15740                     pw.println("):");
15741             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15742             needSep = true;
15743             printedAnything = true;
15744         }
15745
15746         if (dumpAll || dumpPackage != null) {
15747             synchronized (mPidsSelfLocked) {
15748                 boolean printed = false;
15749                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15750                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15751                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15752                         continue;
15753                     }
15754                     if (!printed) {
15755                         if (needSep) pw.println();
15756                         needSep = true;
15757                         pw.println("  PID mappings:");
15758                         printed = true;
15759                         printedAnything = true;
15760                     }
15761                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15762                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15763                 }
15764             }
15765         }
15766
15767         if (mImportantProcesses.size() > 0) {
15768             synchronized (mPidsSelfLocked) {
15769                 boolean printed = false;
15770                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15771                     ProcessRecord r = mPidsSelfLocked.get(
15772                             mImportantProcesses.valueAt(i).pid);
15773                     if (dumpPackage != null && (r == null
15774                             || !r.pkgList.containsKey(dumpPackage))) {
15775                         continue;
15776                     }
15777                     if (!printed) {
15778                         if (needSep) pw.println();
15779                         needSep = true;
15780                         pw.println("  Foreground Processes:");
15781                         printed = true;
15782                         printedAnything = true;
15783                     }
15784                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15785                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15786                 }
15787             }
15788         }
15789
15790         if (mPersistentStartingProcesses.size() > 0) {
15791             if (needSep) pw.println();
15792             needSep = true;
15793             printedAnything = true;
15794             pw.println("  Persisent processes that are starting:");
15795             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15796                     "Starting Norm", "Restarting PERS", dumpPackage);
15797         }
15798
15799         if (mRemovedProcesses.size() > 0) {
15800             if (needSep) pw.println();
15801             needSep = true;
15802             printedAnything = true;
15803             pw.println("  Processes that are being removed:");
15804             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15805                     "Removed Norm", "Removed PERS", dumpPackage);
15806         }
15807
15808         if (mProcessesOnHold.size() > 0) {
15809             if (needSep) pw.println();
15810             needSep = true;
15811             printedAnything = true;
15812             pw.println("  Processes that are on old until the system is ready:");
15813             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15814                     "OnHold Norm", "OnHold PERS", dumpPackage);
15815         }
15816
15817         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15818
15819         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15820         if (needSep) {
15821             printedAnything = true;
15822         }
15823
15824         if (dumpPackage == null) {
15825             pw.println();
15826             needSep = false;
15827             mUserController.dump(pw, dumpAll);
15828         }
15829         if (mHomeProcess != null && (dumpPackage == null
15830                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15831             if (needSep) {
15832                 pw.println();
15833                 needSep = false;
15834             }
15835             pw.println("  mHomeProcess: " + mHomeProcess);
15836         }
15837         if (mPreviousProcess != null && (dumpPackage == null
15838                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15839             if (needSep) {
15840                 pw.println();
15841                 needSep = false;
15842             }
15843             pw.println("  mPreviousProcess: " + mPreviousProcess);
15844         }
15845         if (dumpAll) {
15846             StringBuilder sb = new StringBuilder(128);
15847             sb.append("  mPreviousProcessVisibleTime: ");
15848             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15849             pw.println(sb);
15850         }
15851         if (mHeavyWeightProcess != null && (dumpPackage == null
15852                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15853             if (needSep) {
15854                 pw.println();
15855                 needSep = false;
15856             }
15857             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15858         }
15859         if (dumpPackage == null) {
15860             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15861             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15862         }
15863         if (dumpAll) {
15864             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15865             if (mCompatModePackages.getPackages().size() > 0) {
15866                 boolean printed = false;
15867                 for (Map.Entry<String, Integer> entry
15868                         : mCompatModePackages.getPackages().entrySet()) {
15869                     String pkg = entry.getKey();
15870                     int mode = entry.getValue();
15871                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15872                         continue;
15873                     }
15874                     if (!printed) {
15875                         pw.println("  mScreenCompatPackages:");
15876                         printed = true;
15877                     }
15878                     pw.print("    "); pw.print(pkg); pw.print(": ");
15879                             pw.print(mode); pw.println();
15880                 }
15881             }
15882             final int NI = mUidObservers.getRegisteredCallbackCount();
15883             boolean printed = false;
15884             for (int i=0; i<NI; i++) {
15885                 final UidObserverRegistration reg = (UidObserverRegistration)
15886                         mUidObservers.getRegisteredCallbackCookie(i);
15887                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15888                     if (!printed) {
15889                         pw.println("  mUidObservers:");
15890                         printed = true;
15891                     }
15892                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15893                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15894                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15895                         pw.print(" IDLE");
15896                     }
15897                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15898                         pw.print(" ACT" );
15899                     }
15900                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15901                         pw.print(" GONE");
15902                     }
15903                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15904                         pw.print(" STATE");
15905                         pw.print(" (cut="); pw.print(reg.cutpoint);
15906                         pw.print(")");
15907                     }
15908                     pw.println();
15909                     if (reg.lastProcStates != null) {
15910                         final int NJ = reg.lastProcStates.size();
15911                         for (int j=0; j<NJ; j++) {
15912                             pw.print("      Last ");
15913                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15914                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15915                         }
15916                     }
15917                 }
15918             }
15919             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15920             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15921             if (mPendingTempWhitelist.size() > 0) {
15922                 pw.println("  mPendingTempWhitelist:");
15923                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15924                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15925                     pw.print("    ");
15926                     UserHandle.formatUid(pw, ptw.targetUid);
15927                     pw.print(": ");
15928                     TimeUtils.formatDuration(ptw.duration, pw);
15929                     pw.print(" ");
15930                     pw.println(ptw.tag);
15931                 }
15932             }
15933         }
15934         if (dumpPackage == null) {
15935             pw.println("  mWakefulness="
15936                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15937             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15938             pw.println("  mSleeping=" + mSleeping);
15939             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15940             if (mRunningVoice != null) {
15941                 pw.println("  mRunningVoice=" + mRunningVoice);
15942                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15943             }
15944         }
15945         pw.println("  mVrController=" + mVrController);
15946         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15947                 || mOrigWaitForDebugger) {
15948             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15949                     || dumpPackage.equals(mOrigDebugApp)) {
15950                 if (needSep) {
15951                     pw.println();
15952                     needSep = false;
15953                 }
15954                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15955                         + " mDebugTransient=" + mDebugTransient
15956                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15957             }
15958         }
15959         if (mCurAppTimeTracker != null) {
15960             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15961         }
15962         if (mMemWatchProcesses.getMap().size() > 0) {
15963             pw.println("  Mem watch processes:");
15964             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15965                     = mMemWatchProcesses.getMap();
15966             for (int i=0; i<procs.size(); i++) {
15967                 final String proc = procs.keyAt(i);
15968                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15969                 for (int j=0; j<uids.size(); j++) {
15970                     if (needSep) {
15971                         pw.println();
15972                         needSep = false;
15973                     }
15974                     StringBuilder sb = new StringBuilder();
15975                     sb.append("    ").append(proc).append('/');
15976                     UserHandle.formatUid(sb, uids.keyAt(j));
15977                     Pair<Long, String> val = uids.valueAt(j);
15978                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15979                     if (val.second != null) {
15980                         sb.append(", report to ").append(val.second);
15981                     }
15982                     pw.println(sb.toString());
15983                 }
15984             }
15985             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15986             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15987             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15988                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15989         }
15990         if (mTrackAllocationApp != null) {
15991             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15992                 if (needSep) {
15993                     pw.println();
15994                     needSep = false;
15995                 }
15996                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
15997             }
15998         }
15999         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16000                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16001             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16002                 if (needSep) {
16003                     pw.println();
16004                     needSep = false;
16005                 }
16006                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16007                 if (mProfilerInfo != null) {
16008                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16009                             mProfilerInfo.profileFd);
16010                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16011                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16012                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16013                     pw.println("  mProfileType=" + mProfileType);
16014                 }
16015             }
16016         }
16017         if (mNativeDebuggingApp != null) {
16018             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16019                 if (needSep) {
16020                     pw.println();
16021                     needSep = false;
16022                 }
16023                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16024             }
16025         }
16026         if (dumpPackage == null) {
16027             if (mAlwaysFinishActivities) {
16028                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16029             }
16030             if (mController != null) {
16031                 pw.println("  mController=" + mController
16032                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16033             }
16034             if (dumpAll) {
16035                 pw.println("  Total persistent processes: " + numPers);
16036                 pw.println("  mProcessesReady=" + mProcessesReady
16037                         + " mSystemReady=" + mSystemReady
16038                         + " mBooted=" + mBooted
16039                         + " mFactoryTest=" + mFactoryTest);
16040                 pw.println("  mBooting=" + mBooting
16041                         + " mCallFinishBooting=" + mCallFinishBooting
16042                         + " mBootAnimationComplete=" + mBootAnimationComplete);
16043                 pw.print("  mLastPowerCheckUptime=");
16044                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16045                         pw.println("");
16046                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16047                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16048                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16049                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16050                         + " (" + mLruProcesses.size() + " total)"
16051                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16052                         + " mNumServiceProcs=" + mNumServiceProcs
16053                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16054                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16055                         + " mLastMemoryLevel=" + mLastMemoryLevel
16056                         + " mLastNumProcesses=" + mLastNumProcesses);
16057                 long now = SystemClock.uptimeMillis();
16058                 pw.print("  mLastIdleTime=");
16059                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
16060                         pw.print(" mLowRamSinceLastIdle=");
16061                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16062                         pw.println();
16063             }
16064         }
16065
16066         if (!printedAnything) {
16067             pw.println("  (nothing)");
16068         }
16069     }
16070
16071     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16072             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16073         if (mProcessesToGc.size() > 0) {
16074             boolean printed = false;
16075             long now = SystemClock.uptimeMillis();
16076             for (int i=0; i<mProcessesToGc.size(); i++) {
16077                 ProcessRecord proc = mProcessesToGc.get(i);
16078                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16079                     continue;
16080                 }
16081                 if (!printed) {
16082                     if (needSep) pw.println();
16083                     needSep = true;
16084                     pw.println("  Processes that are waiting to GC:");
16085                     printed = true;
16086                 }
16087                 pw.print("    Process "); pw.println(proc);
16088                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16089                         pw.print(", last gced=");
16090                         pw.print(now-proc.lastRequestedGc);
16091                         pw.print(" ms ago, last lowMem=");
16092                         pw.print(now-proc.lastLowMemory);
16093                         pw.println(" ms ago");
16094
16095             }
16096         }
16097         return needSep;
16098     }
16099
16100     void printOomLevel(PrintWriter pw, String name, int adj) {
16101         pw.print("    ");
16102         if (adj >= 0) {
16103             pw.print(' ');
16104             if (adj < 10) pw.print(' ');
16105         } else {
16106             if (adj > -10) pw.print(' ');
16107         }
16108         pw.print(adj);
16109         pw.print(": ");
16110         pw.print(name);
16111         pw.print(" (");
16112         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16113         pw.println(")");
16114     }
16115
16116     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16117             int opti, boolean dumpAll) {
16118         boolean needSep = false;
16119
16120         if (mLruProcesses.size() > 0) {
16121             if (needSep) pw.println();
16122             needSep = true;
16123             pw.println("  OOM levels:");
16124             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16125             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16126             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16127             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16128             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16129             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16130             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16131             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16132             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16133             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16134             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16135             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16136             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16137             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16138
16139             if (needSep) pw.println();
16140             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16141                     pw.print(" total, non-act at ");
16142                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16143                     pw.print(", non-svc at ");
16144                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16145                     pw.println("):");
16146             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16147             needSep = true;
16148         }
16149
16150         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16151
16152         pw.println();
16153         pw.println("  mHomeProcess: " + mHomeProcess);
16154         pw.println("  mPreviousProcess: " + mPreviousProcess);
16155         if (mHeavyWeightProcess != null) {
16156             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16157         }
16158
16159         return true;
16160     }
16161
16162     /**
16163      * There are three ways to call this:
16164      *  - no provider specified: dump all the providers
16165      *  - a flattened component name that matched an existing provider was specified as the
16166      *    first arg: dump that one provider
16167      *  - the first arg isn't the flattened component name of an existing provider:
16168      *    dump all providers whose component contains the first arg as a substring
16169      */
16170     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16171             int opti, boolean dumpAll) {
16172         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16173     }
16174
16175     static class ItemMatcher {
16176         ArrayList<ComponentName> components;
16177         ArrayList<String> strings;
16178         ArrayList<Integer> objects;
16179         boolean all;
16180
16181         ItemMatcher() {
16182             all = true;
16183         }
16184
16185         void build(String name) {
16186             ComponentName componentName = ComponentName.unflattenFromString(name);
16187             if (componentName != null) {
16188                 if (components == null) {
16189                     components = new ArrayList<ComponentName>();
16190                 }
16191                 components.add(componentName);
16192                 all = false;
16193             } else {
16194                 int objectId = 0;
16195                 // Not a '/' separated full component name; maybe an object ID?
16196                 try {
16197                     objectId = Integer.parseInt(name, 16);
16198                     if (objects == null) {
16199                         objects = new ArrayList<Integer>();
16200                     }
16201                     objects.add(objectId);
16202                     all = false;
16203                 } catch (RuntimeException e) {
16204                     // Not an integer; just do string match.
16205                     if (strings == null) {
16206                         strings = new ArrayList<String>();
16207                     }
16208                     strings.add(name);
16209                     all = false;
16210                 }
16211             }
16212         }
16213
16214         int build(String[] args, int opti) {
16215             for (; opti<args.length; opti++) {
16216                 String name = args[opti];
16217                 if ("--".equals(name)) {
16218                     return opti+1;
16219                 }
16220                 build(name);
16221             }
16222             return opti;
16223         }
16224
16225         boolean match(Object object, ComponentName comp) {
16226             if (all) {
16227                 return true;
16228             }
16229             if (components != null) {
16230                 for (int i=0; i<components.size(); i++) {
16231                     if (components.get(i).equals(comp)) {
16232                         return true;
16233                     }
16234                 }
16235             }
16236             if (objects != null) {
16237                 for (int i=0; i<objects.size(); i++) {
16238                     if (System.identityHashCode(object) == objects.get(i)) {
16239                         return true;
16240                     }
16241                 }
16242             }
16243             if (strings != null) {
16244                 String flat = comp.flattenToString();
16245                 for (int i=0; i<strings.size(); i++) {
16246                     if (flat.contains(strings.get(i))) {
16247                         return true;
16248                     }
16249                 }
16250             }
16251             return false;
16252         }
16253     }
16254
16255     /**
16256      * There are three things that cmd can be:
16257      *  - a flattened component name that matches an existing activity
16258      *  - the cmd arg isn't the flattened component name of an existing activity:
16259      *    dump all activity whose component contains the cmd as a substring
16260      *  - A hex number of the ActivityRecord object instance.
16261      *
16262      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16263      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16264      */
16265     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16266             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16267         ArrayList<ActivityRecord> activities;
16268
16269         synchronized (this) {
16270             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16271                     dumpFocusedStackOnly);
16272         }
16273
16274         if (activities.size() <= 0) {
16275             return false;
16276         }
16277
16278         String[] newArgs = new String[args.length - opti];
16279         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16280
16281         TaskRecord lastTask = null;
16282         boolean needSep = false;
16283         for (int i=activities.size()-1; i>=0; i--) {
16284             ActivityRecord r = activities.get(i);
16285             if (needSep) {
16286                 pw.println();
16287             }
16288             needSep = true;
16289             synchronized (this) {
16290                 final TaskRecord task = r.getTask();
16291                 if (lastTask != task) {
16292                     lastTask = task;
16293                     pw.print("TASK "); pw.print(lastTask.affinity);
16294                             pw.print(" id="); pw.print(lastTask.taskId);
16295                             pw.print(" userId="); pw.println(lastTask.userId);
16296                     if (dumpAll) {
16297                         lastTask.dump(pw, "  ");
16298                     }
16299                 }
16300             }
16301             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16302         }
16303         return true;
16304     }
16305
16306     /**
16307      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16308      * there is a thread associated with the activity.
16309      */
16310     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16311             final ActivityRecord r, String[] args, boolean dumpAll) {
16312         String innerPrefix = prefix + "  ";
16313         synchronized (this) {
16314             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16315                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16316                     pw.print(" pid=");
16317                     if (r.app != null) pw.println(r.app.pid);
16318                     else pw.println("(not running)");
16319             if (dumpAll) {
16320                 r.dump(pw, innerPrefix);
16321             }
16322         }
16323         if (r.app != null && r.app.thread != null) {
16324             // flush anything that is already in the PrintWriter since the thread is going
16325             // to write to the file descriptor directly
16326             pw.flush();
16327             try {
16328                 TransferPipe tp = new TransferPipe();
16329                 try {
16330                     r.app.thread.dumpActivity(tp.getWriteFd(),
16331                             r.appToken, innerPrefix, args);
16332                     tp.go(fd);
16333                 } finally {
16334                     tp.kill();
16335                 }
16336             } catch (IOException e) {
16337                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16338             } catch (RemoteException e) {
16339                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16340             }
16341         }
16342     }
16343
16344     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16345             int opti, boolean dumpAll, String dumpPackage) {
16346         boolean needSep = false;
16347         boolean onlyHistory = false;
16348         boolean printedAnything = false;
16349
16350         if ("history".equals(dumpPackage)) {
16351             if (opti < args.length && "-s".equals(args[opti])) {
16352                 dumpAll = false;
16353             }
16354             onlyHistory = true;
16355             dumpPackage = null;
16356         }
16357
16358         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16359         if (!onlyHistory && dumpAll) {
16360             if (mRegisteredReceivers.size() > 0) {
16361                 boolean printed = false;
16362                 Iterator it = mRegisteredReceivers.values().iterator();
16363                 while (it.hasNext()) {
16364                     ReceiverList r = (ReceiverList)it.next();
16365                     if (dumpPackage != null && (r.app == null ||
16366                             !dumpPackage.equals(r.app.info.packageName))) {
16367                         continue;
16368                     }
16369                     if (!printed) {
16370                         pw.println("  Registered Receivers:");
16371                         needSep = true;
16372                         printed = true;
16373                         printedAnything = true;
16374                     }
16375                     pw.print("  * "); pw.println(r);
16376                     r.dump(pw, "    ");
16377                 }
16378             }
16379
16380             if (mReceiverResolver.dump(pw, needSep ?
16381                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16382                     "    ", dumpPackage, false, false)) {
16383                 needSep = true;
16384                 printedAnything = true;
16385             }
16386         }
16387
16388         for (BroadcastQueue q : mBroadcastQueues) {
16389             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16390             printedAnything |= needSep;
16391         }
16392
16393         needSep = true;
16394
16395         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16396             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16397                 if (needSep) {
16398                     pw.println();
16399                 }
16400                 needSep = true;
16401                 printedAnything = true;
16402                 pw.print("  Sticky broadcasts for user ");
16403                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16404                 StringBuilder sb = new StringBuilder(128);
16405                 for (Map.Entry<String, ArrayList<Intent>> ent
16406                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16407                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16408                     if (dumpAll) {
16409                         pw.println(":");
16410                         ArrayList<Intent> intents = ent.getValue();
16411                         final int N = intents.size();
16412                         for (int i=0; i<N; i++) {
16413                             sb.setLength(0);
16414                             sb.append("    Intent: ");
16415                             intents.get(i).toShortString(sb, false, true, false, false);
16416                             pw.println(sb.toString());
16417                             Bundle bundle = intents.get(i).getExtras();
16418                             if (bundle != null) {
16419                                 pw.print("      ");
16420                                 pw.println(bundle.toString());
16421                             }
16422                         }
16423                     } else {
16424                         pw.println("");
16425                     }
16426                 }
16427             }
16428         }
16429
16430         if (!onlyHistory && dumpAll) {
16431             pw.println();
16432             for (BroadcastQueue queue : mBroadcastQueues) {
16433                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16434                         + queue.mBroadcastsScheduled);
16435             }
16436             pw.println("  mHandler:");
16437             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16438             needSep = true;
16439             printedAnything = true;
16440         }
16441
16442         if (!printedAnything) {
16443             pw.println("  (nothing)");
16444         }
16445     }
16446
16447     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16448             int opti, boolean dumpAll, String dumpPackage) {
16449         if (mCurBroadcastStats == null) {
16450             return;
16451         }
16452
16453         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16454         final long now = SystemClock.elapsedRealtime();
16455         if (mLastBroadcastStats != null) {
16456             pw.print("  Last stats (from ");
16457             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16458             pw.print(" to ");
16459             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16460             pw.print(", ");
16461             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16462                     - mLastBroadcastStats.mStartUptime, pw);
16463             pw.println(" uptime):");
16464             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16465                 pw.println("    (nothing)");
16466             }
16467             pw.println();
16468         }
16469         pw.print("  Current stats (from ");
16470         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16471         pw.print(" to now, ");
16472         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16473                 - mCurBroadcastStats.mStartUptime, pw);
16474         pw.println(" uptime):");
16475         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16476             pw.println("    (nothing)");
16477         }
16478     }
16479
16480     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16481             int opti, boolean fullCheckin, String dumpPackage) {
16482         if (mCurBroadcastStats == null) {
16483             return;
16484         }
16485
16486         if (mLastBroadcastStats != null) {
16487             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16488             if (fullCheckin) {
16489                 mLastBroadcastStats = null;
16490                 return;
16491             }
16492         }
16493         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16494         if (fullCheckin) {
16495             mCurBroadcastStats = null;
16496         }
16497     }
16498
16499     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16500             int opti, boolean dumpAll, String dumpPackage) {
16501         boolean needSep;
16502         boolean printedAnything = false;
16503
16504         ItemMatcher matcher = new ItemMatcher();
16505         matcher.build(args, opti);
16506
16507         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16508
16509         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16510         printedAnything |= needSep;
16511
16512         if (mLaunchingProviders.size() > 0) {
16513             boolean printed = false;
16514             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16515                 ContentProviderRecord r = mLaunchingProviders.get(i);
16516                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16517                     continue;
16518                 }
16519                 if (!printed) {
16520                     if (needSep) pw.println();
16521                     needSep = true;
16522                     pw.println("  Launching content providers:");
16523                     printed = true;
16524                     printedAnything = true;
16525                 }
16526                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16527                         pw.println(r);
16528             }
16529         }
16530
16531         if (!printedAnything) {
16532             pw.println("  (nothing)");
16533         }
16534     }
16535
16536     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16537             int opti, boolean dumpAll, String dumpPackage) {
16538         boolean needSep = false;
16539         boolean printedAnything = false;
16540
16541         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16542
16543         if (mGrantedUriPermissions.size() > 0) {
16544             boolean printed = false;
16545             int dumpUid = -2;
16546             if (dumpPackage != null) {
16547                 try {
16548                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16549                             MATCH_ANY_USER, 0);
16550                 } catch (NameNotFoundException e) {
16551                     dumpUid = -1;
16552                 }
16553             }
16554             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16555                 int uid = mGrantedUriPermissions.keyAt(i);
16556                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16557                     continue;
16558                 }
16559                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16560                 if (!printed) {
16561                     if (needSep) pw.println();
16562                     needSep = true;
16563                     pw.println("  Granted Uri Permissions:");
16564                     printed = true;
16565                     printedAnything = true;
16566                 }
16567                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16568                 for (UriPermission perm : perms.values()) {
16569                     pw.print("    "); pw.println(perm);
16570                     if (dumpAll) {
16571                         perm.dump(pw, "      ");
16572                     }
16573                 }
16574             }
16575         }
16576
16577         if (!printedAnything) {
16578             pw.println("  (nothing)");
16579         }
16580     }
16581
16582     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16583             int opti, boolean dumpAll, String dumpPackage) {
16584         boolean printed = false;
16585
16586         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16587
16588         if (mIntentSenderRecords.size() > 0) {
16589             // Organize these by package name, so they are easier to read.
16590             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16591             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16592             final Iterator<WeakReference<PendingIntentRecord>> it
16593                     = mIntentSenderRecords.values().iterator();
16594             while (it.hasNext()) {
16595                 WeakReference<PendingIntentRecord> ref = it.next();
16596                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16597                 if (rec == null) {
16598                     weakRefs.add(ref);
16599                     continue;
16600                 }
16601                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16602                     continue;
16603                 }
16604                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16605                 if (list == null) {
16606                     list = new ArrayList<>();
16607                     byPackage.put(rec.key.packageName, list);
16608                 }
16609                 list.add(rec);
16610             }
16611             for (int i = 0; i < byPackage.size(); i++) {
16612                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16613                 printed = true;
16614                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16615                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16616                 for (int j = 0; j < intents.size(); j++) {
16617                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16618                     if (dumpAll) {
16619                         intents.get(j).dump(pw, "      ");
16620                     }
16621                 }
16622             }
16623             if (weakRefs.size() > 0) {
16624                 printed = true;
16625                 pw.println("  * WEAK REFS:");
16626                 for (int i = 0; i < weakRefs.size(); i++) {
16627                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16628                 }
16629             }
16630         }
16631
16632         if (!printed) {
16633             pw.println("  (nothing)");
16634         }
16635     }
16636
16637     private static final int dumpProcessList(PrintWriter pw,
16638             ActivityManagerService service, List list,
16639             String prefix, String normalLabel, String persistentLabel,
16640             String dumpPackage) {
16641         int numPers = 0;
16642         final int N = list.size()-1;
16643         for (int i=N; i>=0; i--) {
16644             ProcessRecord r = (ProcessRecord)list.get(i);
16645             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16646                 continue;
16647             }
16648             pw.println(String.format("%s%s #%2d: %s",
16649                     prefix, (r.persistent ? persistentLabel : normalLabel),
16650                     i, r.toString()));
16651             if (r.persistent) {
16652                 numPers++;
16653             }
16654         }
16655         return numPers;
16656     }
16657
16658     private static final boolean dumpProcessOomList(PrintWriter pw,
16659             ActivityManagerService service, List<ProcessRecord> origList,
16660             String prefix, String normalLabel, String persistentLabel,
16661             boolean inclDetails, String dumpPackage) {
16662
16663         ArrayList<Pair<ProcessRecord, Integer>> list
16664                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16665         for (int i=0; i<origList.size(); i++) {
16666             ProcessRecord r = origList.get(i);
16667             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16668                 continue;
16669             }
16670             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16671         }
16672
16673         if (list.size() <= 0) {
16674             return false;
16675         }
16676
16677         Comparator<Pair<ProcessRecord, Integer>> comparator
16678                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16679             @Override
16680             public int compare(Pair<ProcessRecord, Integer> object1,
16681                     Pair<ProcessRecord, Integer> object2) {
16682                 if (object1.first.setAdj != object2.first.setAdj) {
16683                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16684                 }
16685                 if (object1.first.setProcState != object2.first.setProcState) {
16686                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16687                 }
16688                 if (object1.second.intValue() != object2.second.intValue()) {
16689                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16690                 }
16691                 return 0;
16692             }
16693         };
16694
16695         Collections.sort(list, comparator);
16696
16697         final long curUptime = SystemClock.uptimeMillis();
16698         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16699
16700         for (int i=list.size()-1; i>=0; i--) {
16701             ProcessRecord r = list.get(i).first;
16702             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16703             char schedGroup;
16704             switch (r.setSchedGroup) {
16705                 case ProcessList.SCHED_GROUP_BACKGROUND:
16706                     schedGroup = 'B';
16707                     break;
16708                 case ProcessList.SCHED_GROUP_DEFAULT:
16709                     schedGroup = 'F';
16710                     break;
16711                 case ProcessList.SCHED_GROUP_TOP_APP:
16712                     schedGroup = 'T';
16713                     break;
16714                 default:
16715                     schedGroup = '?';
16716                     break;
16717             }
16718             char foreground;
16719             if (r.foregroundActivities) {
16720                 foreground = 'A';
16721             } else if (r.foregroundServices) {
16722                 foreground = 'S';
16723             } else {
16724                 foreground = ' ';
16725             }
16726             String procState = ProcessList.makeProcStateString(r.curProcState);
16727             pw.print(prefix);
16728             pw.print(r.persistent ? persistentLabel : normalLabel);
16729             pw.print(" #");
16730             int num = (origList.size()-1)-list.get(i).second;
16731             if (num < 10) pw.print(' ');
16732             pw.print(num);
16733             pw.print(": ");
16734             pw.print(oomAdj);
16735             pw.print(' ');
16736             pw.print(schedGroup);
16737             pw.print('/');
16738             pw.print(foreground);
16739             pw.print('/');
16740             pw.print(procState);
16741             pw.print(" trm:");
16742             if (r.trimMemoryLevel < 10) pw.print(' ');
16743             pw.print(r.trimMemoryLevel);
16744             pw.print(' ');
16745             pw.print(r.toShortString());
16746             pw.print(" (");
16747             pw.print(r.adjType);
16748             pw.println(')');
16749             if (r.adjSource != null || r.adjTarget != null) {
16750                 pw.print(prefix);
16751                 pw.print("    ");
16752                 if (r.adjTarget instanceof ComponentName) {
16753                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16754                 } else if (r.adjTarget != null) {
16755                     pw.print(r.adjTarget.toString());
16756                 } else {
16757                     pw.print("{null}");
16758                 }
16759                 pw.print("<=");
16760                 if (r.adjSource instanceof ProcessRecord) {
16761                     pw.print("Proc{");
16762                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16763                     pw.println("}");
16764                 } else if (r.adjSource != null) {
16765                     pw.println(r.adjSource.toString());
16766                 } else {
16767                     pw.println("{null}");
16768                 }
16769             }
16770             if (inclDetails) {
16771                 pw.print(prefix);
16772                 pw.print("    ");
16773                 pw.print("oom: max="); pw.print(r.maxAdj);
16774                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16775                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16776                 pw.print(" cur="); pw.print(r.curAdj);
16777                 pw.print(" set="); pw.println(r.setAdj);
16778                 pw.print(prefix);
16779                 pw.print("    ");
16780                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16781                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16782                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16783                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16784                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16785                 pw.println();
16786                 pw.print(prefix);
16787                 pw.print("    ");
16788                 pw.print("cached="); pw.print(r.cached);
16789                 pw.print(" empty="); pw.print(r.empty);
16790                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16791
16792                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16793                     if (r.lastCpuTime != 0) {
16794                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16795                         pw.print(prefix);
16796                         pw.print("    ");
16797                         pw.print("run cpu over ");
16798                         TimeUtils.formatDuration(uptimeSince, pw);
16799                         pw.print(" used ");
16800                         TimeUtils.formatDuration(timeUsed, pw);
16801                         pw.print(" (");
16802                         pw.print((timeUsed*100)/uptimeSince);
16803                         pw.println("%)");
16804                     }
16805                 }
16806             }
16807         }
16808         return true;
16809     }
16810
16811     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16812             String[] args) {
16813         ArrayList<ProcessRecord> procs;
16814         synchronized (this) {
16815             if (args != null && args.length > start
16816                     && args[start].charAt(0) != '-') {
16817                 procs = new ArrayList<ProcessRecord>();
16818                 int pid = -1;
16819                 try {
16820                     pid = Integer.parseInt(args[start]);
16821                 } catch (NumberFormatException e) {
16822                 }
16823                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16824                     ProcessRecord proc = mLruProcesses.get(i);
16825                     if (proc.pid == pid) {
16826                         procs.add(proc);
16827                     } else if (allPkgs && proc.pkgList != null
16828                             && proc.pkgList.containsKey(args[start])) {
16829                         procs.add(proc);
16830                     } else if (proc.processName.equals(args[start])) {
16831                         procs.add(proc);
16832                     }
16833                 }
16834                 if (procs.size() <= 0) {
16835                     return null;
16836                 }
16837             } else {
16838                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16839             }
16840         }
16841         return procs;
16842     }
16843
16844     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16845             PrintWriter pw, String[] args) {
16846         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16847         if (procs == null) {
16848             pw.println("No process found for: " + args[0]);
16849             return;
16850         }
16851
16852         long uptime = SystemClock.uptimeMillis();
16853         long realtime = SystemClock.elapsedRealtime();
16854         pw.println("Applications Graphics Acceleration Info:");
16855         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16856
16857         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16858             ProcessRecord r = procs.get(i);
16859             if (r.thread != null) {
16860                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16861                 pw.flush();
16862                 try {
16863                     TransferPipe tp = new TransferPipe();
16864                     try {
16865                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16866                         tp.go(fd);
16867                     } finally {
16868                         tp.kill();
16869                     }
16870                 } catch (IOException e) {
16871                     pw.println("Failure while dumping the app: " + r);
16872                     pw.flush();
16873                 } catch (RemoteException e) {
16874                     pw.println("Got a RemoteException while dumping the app " + r);
16875                     pw.flush();
16876                 }
16877             }
16878         }
16879     }
16880
16881     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16882         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16883         if (procs == null) {
16884             pw.println("No process found for: " + args[0]);
16885             return;
16886         }
16887
16888         pw.println("Applications Database Info:");
16889
16890         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16891             ProcessRecord r = procs.get(i);
16892             if (r.thread != null) {
16893                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16894                 pw.flush();
16895                 try {
16896                     TransferPipe tp = new TransferPipe();
16897                     try {
16898                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16899                         tp.go(fd);
16900                     } finally {
16901                         tp.kill();
16902                     }
16903                 } catch (IOException e) {
16904                     pw.println("Failure while dumping the app: " + r);
16905                     pw.flush();
16906                 } catch (RemoteException e) {
16907                     pw.println("Got a RemoteException while dumping the app " + r);
16908                     pw.flush();
16909                 }
16910             }
16911         }
16912     }
16913
16914     final static class MemItem {
16915         final boolean isProc;
16916         final String label;
16917         final String shortLabel;
16918         final long pss;
16919         final long swapPss;
16920         final int id;
16921         final boolean hasActivities;
16922         ArrayList<MemItem> subitems;
16923
16924         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16925                 boolean _hasActivities) {
16926             isProc = true;
16927             label = _label;
16928             shortLabel = _shortLabel;
16929             pss = _pss;
16930             swapPss = _swapPss;
16931             id = _id;
16932             hasActivities = _hasActivities;
16933         }
16934
16935         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16936             isProc = false;
16937             label = _label;
16938             shortLabel = _shortLabel;
16939             pss = _pss;
16940             swapPss = _swapPss;
16941             id = _id;
16942             hasActivities = false;
16943         }
16944     }
16945
16946     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16947             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16948         if (sort && !isCompact) {
16949             Collections.sort(items, new Comparator<MemItem>() {
16950                 @Override
16951                 public int compare(MemItem lhs, MemItem rhs) {
16952                     if (lhs.pss < rhs.pss) {
16953                         return 1;
16954                     } else if (lhs.pss > rhs.pss) {
16955                         return -1;
16956                     }
16957                     return 0;
16958                 }
16959             });
16960         }
16961
16962         for (int i=0; i<items.size(); i++) {
16963             MemItem mi = items.get(i);
16964             if (!isCompact) {
16965                 if (dumpSwapPss) {
16966                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16967                             mi.label, stringifyKBSize(mi.swapPss));
16968                 } else {
16969                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16970                 }
16971             } else if (mi.isProc) {
16972                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16973                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16974                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16975                 pw.println(mi.hasActivities ? ",a" : ",e");
16976             } else {
16977                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16978                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16979             }
16980             if (mi.subitems != null) {
16981                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16982                         true, isCompact, dumpSwapPss);
16983             }
16984         }
16985     }
16986
16987     // These are in KB.
16988     static final long[] DUMP_MEM_BUCKETS = new long[] {
16989         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16990         120*1024, 160*1024, 200*1024,
16991         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16992         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16993     };
16994
16995     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16996             boolean stackLike) {
16997         int start = label.lastIndexOf('.');
16998         if (start >= 0) start++;
16999         else start = 0;
17000         int end = label.length();
17001         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17002             if (DUMP_MEM_BUCKETS[i] >= memKB) {
17003                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17004                 out.append(bucket);
17005                 out.append(stackLike ? "MB." : "MB ");
17006                 out.append(label, start, end);
17007                 return;
17008             }
17009         }
17010         out.append(memKB/1024);
17011         out.append(stackLike ? "MB." : "MB ");
17012         out.append(label, start, end);
17013     }
17014
17015     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17016             ProcessList.NATIVE_ADJ,
17017             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17018             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17019             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17020             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17021             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17022             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17023     };
17024     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17025             "Native",
17026             "System", "Persistent", "Persistent Service", "Foreground",
17027             "Visible", "Perceptible",
17028             "Heavy Weight", "Backup",
17029             "A Services", "Home",
17030             "Previous", "B Services", "Cached"
17031     };
17032     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17033             "native",
17034             "sys", "pers", "persvc", "fore",
17035             "vis", "percept",
17036             "heavy", "backup",
17037             "servicea", "home",
17038             "prev", "serviceb", "cached"
17039     };
17040
17041     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17042             long realtime, boolean isCheckinRequest, boolean isCompact) {
17043         if (isCompact) {
17044             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17045         }
17046         if (isCheckinRequest || isCompact) {
17047             // short checkin version
17048             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17049         } else {
17050             pw.println("Applications Memory Usage (in Kilobytes):");
17051             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17052         }
17053     }
17054
17055     private static final int KSM_SHARED = 0;
17056     private static final int KSM_SHARING = 1;
17057     private static final int KSM_UNSHARED = 2;
17058     private static final int KSM_VOLATILE = 3;
17059
17060     private final long[] getKsmInfo() {
17061         long[] longOut = new long[4];
17062         final int[] SINGLE_LONG_FORMAT = new int[] {
17063             PROC_SPACE_TERM| PROC_OUT_LONG
17064         };
17065         long[] longTmp = new long[1];
17066         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17067                 SINGLE_LONG_FORMAT, null, longTmp, null);
17068         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17069         longTmp[0] = 0;
17070         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17071                 SINGLE_LONG_FORMAT, null, longTmp, null);
17072         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17073         longTmp[0] = 0;
17074         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17075                 SINGLE_LONG_FORMAT, null, longTmp, null);
17076         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17077         longTmp[0] = 0;
17078         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17079                 SINGLE_LONG_FORMAT, null, longTmp, null);
17080         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17081         return longOut;
17082     }
17083
17084     private static String stringifySize(long size, int order) {
17085         Locale locale = Locale.US;
17086         switch (order) {
17087             case 1:
17088                 return String.format(locale, "%,13d", size);
17089             case 1024:
17090                 return String.format(locale, "%,9dK", size / 1024);
17091             case 1024 * 1024:
17092                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17093             case 1024 * 1024 * 1024:
17094                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17095             default:
17096                 throw new IllegalArgumentException("Invalid size order");
17097         }
17098     }
17099
17100     private static String stringifyKBSize(long size) {
17101         return stringifySize(size * 1024, 1024);
17102     }
17103
17104     // Update this version number in case you change the 'compact' format
17105     private static final int MEMINFO_COMPACT_VERSION = 1;
17106
17107     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17108             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17109         boolean dumpDetails = false;
17110         boolean dumpFullDetails = false;
17111         boolean dumpDalvik = false;
17112         boolean dumpSummaryOnly = false;
17113         boolean dumpUnreachable = false;
17114         boolean oomOnly = false;
17115         boolean isCompact = false;
17116         boolean localOnly = false;
17117         boolean packages = false;
17118         boolean isCheckinRequest = false;
17119         boolean dumpSwapPss = false;
17120
17121         int opti = 0;
17122         while (opti < args.length) {
17123             String opt = args[opti];
17124             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17125                 break;
17126             }
17127             opti++;
17128             if ("-a".equals(opt)) {
17129                 dumpDetails = true;
17130                 dumpFullDetails = true;
17131                 dumpDalvik = true;
17132                 dumpSwapPss = true;
17133             } else if ("-d".equals(opt)) {
17134                 dumpDalvik = true;
17135             } else if ("-c".equals(opt)) {
17136                 isCompact = true;
17137             } else if ("-s".equals(opt)) {
17138                 dumpDetails = true;
17139                 dumpSummaryOnly = true;
17140             } else if ("-S".equals(opt)) {
17141                 dumpSwapPss = true;
17142             } else if ("--unreachable".equals(opt)) {
17143                 dumpUnreachable = true;
17144             } else if ("--oom".equals(opt)) {
17145                 oomOnly = true;
17146             } else if ("--local".equals(opt)) {
17147                 localOnly = true;
17148             } else if ("--package".equals(opt)) {
17149                 packages = true;
17150             } else if ("--checkin".equals(opt)) {
17151                 isCheckinRequest = true;
17152
17153             } else if ("-h".equals(opt)) {
17154                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17155                 pw.println("  -a: include all available information for each process.");
17156                 pw.println("  -d: include dalvik details.");
17157                 pw.println("  -c: dump in a compact machine-parseable representation.");
17158                 pw.println("  -s: dump only summary of application memory usage.");
17159                 pw.println("  -S: dump also SwapPss.");
17160                 pw.println("  --oom: only show processes organized by oom adj.");
17161                 pw.println("  --local: only collect details locally, don't call process.");
17162                 pw.println("  --package: interpret process arg as package, dumping all");
17163                 pw.println("             processes that have loaded that package.");
17164                 pw.println("  --checkin: dump data for a checkin");
17165                 pw.println("If [process] is specified it can be the name or ");
17166                 pw.println("pid of a specific process to dump.");
17167                 return;
17168             } else {
17169                 pw.println("Unknown argument: " + opt + "; use -h for help");
17170             }
17171         }
17172
17173         long uptime = SystemClock.uptimeMillis();
17174         long realtime = SystemClock.elapsedRealtime();
17175         final long[] tmpLong = new long[1];
17176
17177         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17178         if (procs == null) {
17179             // No Java processes.  Maybe they want to print a native process.
17180             if (args != null && args.length > opti
17181                     && args[opti].charAt(0) != '-') {
17182                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17183                         = new ArrayList<ProcessCpuTracker.Stats>();
17184                 updateCpuStatsNow();
17185                 int findPid = -1;
17186                 try {
17187                     findPid = Integer.parseInt(args[opti]);
17188                 } catch (NumberFormatException e) {
17189                 }
17190                 synchronized (mProcessCpuTracker) {
17191                     final int N = mProcessCpuTracker.countStats();
17192                     for (int i=0; i<N; i++) {
17193                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17194                         if (st.pid == findPid || (st.baseName != null
17195                                 && st.baseName.equals(args[opti]))) {
17196                             nativeProcs.add(st);
17197                         }
17198                     }
17199                 }
17200                 if (nativeProcs.size() > 0) {
17201                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17202                             isCompact);
17203                     Debug.MemoryInfo mi = null;
17204                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17205                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17206                         final int pid = r.pid;
17207                         if (!isCheckinRequest && dumpDetails) {
17208                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17209                         }
17210                         if (mi == null) {
17211                             mi = new Debug.MemoryInfo();
17212                         }
17213                         if (dumpDetails || (!brief && !oomOnly)) {
17214                             Debug.getMemoryInfo(pid, mi);
17215                         } else {
17216                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17217                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17218                         }
17219                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17220                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17221                         if (isCheckinRequest) {
17222                             pw.println();
17223                         }
17224                     }
17225                     return;
17226                 }
17227             }
17228             pw.println("No process found for: " + args[opti]);
17229             return;
17230         }
17231
17232         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17233             dumpDetails = true;
17234         }
17235
17236         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17237
17238         String[] innerArgs = new String[args.length-opti];
17239         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17240
17241         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17242         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17243         long nativePss = 0;
17244         long nativeSwapPss = 0;
17245         long dalvikPss = 0;
17246         long dalvikSwapPss = 0;
17247         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17248                 EmptyArray.LONG;
17249         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17250                 EmptyArray.LONG;
17251         long otherPss = 0;
17252         long otherSwapPss = 0;
17253         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17254         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17255
17256         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17257         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17258         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17259                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17260
17261         long totalPss = 0;
17262         long totalSwapPss = 0;
17263         long cachedPss = 0;
17264         long cachedSwapPss = 0;
17265         boolean hasSwapPss = false;
17266
17267         Debug.MemoryInfo mi = null;
17268         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17269             final ProcessRecord r = procs.get(i);
17270             final IApplicationThread thread;
17271             final int pid;
17272             final int oomAdj;
17273             final boolean hasActivities;
17274             synchronized (this) {
17275                 thread = r.thread;
17276                 pid = r.pid;
17277                 oomAdj = r.getSetAdjWithServices();
17278                 hasActivities = r.activities.size() > 0;
17279             }
17280             if (thread != null) {
17281                 if (!isCheckinRequest && dumpDetails) {
17282                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17283                 }
17284                 if (mi == null) {
17285                     mi = new Debug.MemoryInfo();
17286                 }
17287                 if (dumpDetails || (!brief && !oomOnly)) {
17288                     Debug.getMemoryInfo(pid, mi);
17289                     hasSwapPss = mi.hasSwappedOutPss;
17290                 } else {
17291                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17292                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17293                 }
17294                 if (dumpDetails) {
17295                     if (localOnly) {
17296                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17297                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17298                         if (isCheckinRequest) {
17299                             pw.println();
17300                         }
17301                     } else {
17302                         pw.flush();
17303                         try {
17304                             TransferPipe tp = new TransferPipe();
17305                             try {
17306                                 thread.dumpMemInfo(tp.getWriteFd(),
17307                                         mi, isCheckinRequest, dumpFullDetails,
17308                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17309                                 tp.go(fd);
17310                             } finally {
17311                                 tp.kill();
17312                             }
17313                         } catch (IOException e) {
17314                             if (!isCheckinRequest) {
17315                                 pw.println("Got IoException! " + e);
17316                                 pw.flush();
17317                             }
17318                         } catch (RemoteException e) {
17319                             if (!isCheckinRequest) {
17320                                 pw.println("Got RemoteException! " + e);
17321                                 pw.flush();
17322                             }
17323                         }
17324                     }
17325                 }
17326
17327                 final long myTotalPss = mi.getTotalPss();
17328                 final long myTotalUss = mi.getTotalUss();
17329                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17330
17331                 synchronized (this) {
17332                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17333                         // Record this for posterity if the process has been stable.
17334                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17335                     }
17336                 }
17337
17338                 if (!isCheckinRequest && mi != null) {
17339                     totalPss += myTotalPss;
17340                     totalSwapPss += myTotalSwapPss;
17341                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17342                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17343                             myTotalSwapPss, pid, hasActivities);
17344                     procMems.add(pssItem);
17345                     procMemsMap.put(pid, pssItem);
17346
17347                     nativePss += mi.nativePss;
17348                     nativeSwapPss += mi.nativeSwappedOutPss;
17349                     dalvikPss += mi.dalvikPss;
17350                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17351                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17352                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17353                         dalvikSubitemSwapPss[j] +=
17354                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17355                     }
17356                     otherPss += mi.otherPss;
17357                     otherSwapPss += mi.otherSwappedOutPss;
17358                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17359                         long mem = mi.getOtherPss(j);
17360                         miscPss[j] += mem;
17361                         otherPss -= mem;
17362                         mem = mi.getOtherSwappedOutPss(j);
17363                         miscSwapPss[j] += mem;
17364                         otherSwapPss -= mem;
17365                     }
17366
17367                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17368                         cachedPss += myTotalPss;
17369                         cachedSwapPss += myTotalSwapPss;
17370                     }
17371
17372                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17373                         if (oomIndex == (oomPss.length - 1)
17374                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17375                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17376                             oomPss[oomIndex] += myTotalPss;
17377                             oomSwapPss[oomIndex] += myTotalSwapPss;
17378                             if (oomProcs[oomIndex] == null) {
17379                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17380                             }
17381                             oomProcs[oomIndex].add(pssItem);
17382                             break;
17383                         }
17384                     }
17385                 }
17386             }
17387         }
17388
17389         long nativeProcTotalPss = 0;
17390
17391         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17392             // If we are showing aggregations, also look for native processes to
17393             // include so that our aggregations are more accurate.
17394             updateCpuStatsNow();
17395             mi = null;
17396             synchronized (mProcessCpuTracker) {
17397                 final int N = mProcessCpuTracker.countStats();
17398                 for (int i=0; i<N; i++) {
17399                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17400                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17401                         if (mi == null) {
17402                             mi = new Debug.MemoryInfo();
17403                         }
17404                         if (!brief && !oomOnly) {
17405                             Debug.getMemoryInfo(st.pid, mi);
17406                         } else {
17407                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17408                             mi.nativePrivateDirty = (int)tmpLong[0];
17409                         }
17410
17411                         final long myTotalPss = mi.getTotalPss();
17412                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17413                         totalPss += myTotalPss;
17414                         nativeProcTotalPss += myTotalPss;
17415
17416                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17417                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17418                         procMems.add(pssItem);
17419
17420                         nativePss += mi.nativePss;
17421                         nativeSwapPss += mi.nativeSwappedOutPss;
17422                         dalvikPss += mi.dalvikPss;
17423                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17424                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17425                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17426                             dalvikSubitemSwapPss[j] +=
17427                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17428                         }
17429                         otherPss += mi.otherPss;
17430                         otherSwapPss += mi.otherSwappedOutPss;
17431                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17432                             long mem = mi.getOtherPss(j);
17433                             miscPss[j] += mem;
17434                             otherPss -= mem;
17435                             mem = mi.getOtherSwappedOutPss(j);
17436                             miscSwapPss[j] += mem;
17437                             otherSwapPss -= mem;
17438                         }
17439                         oomPss[0] += myTotalPss;
17440                         oomSwapPss[0] += myTotalSwapPss;
17441                         if (oomProcs[0] == null) {
17442                             oomProcs[0] = new ArrayList<MemItem>();
17443                         }
17444                         oomProcs[0].add(pssItem);
17445                     }
17446                 }
17447             }
17448
17449             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17450
17451             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17452             final int dalvikId = -2;
17453             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17454             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17455             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17456                 String label = Debug.MemoryInfo.getOtherLabel(j);
17457                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17458             }
17459             if (dalvikSubitemPss.length > 0) {
17460                 // Add dalvik subitems.
17461                 for (MemItem memItem : catMems) {
17462                     int memItemStart = 0, memItemEnd = 0;
17463                     if (memItem.id == dalvikId) {
17464                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17465                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17466                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17467                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17468                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17469                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17470                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17471                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17472                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17473                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17474                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17475                     } else {
17476                         continue;  // No subitems, continue.
17477                     }
17478                     memItem.subitems = new ArrayList<MemItem>();
17479                     for (int j=memItemStart; j<=memItemEnd; j++) {
17480                         final String name = Debug.MemoryInfo.getOtherLabel(
17481                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17482                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17483                                 dalvikSubitemSwapPss[j], j));
17484                     }
17485                 }
17486             }
17487
17488             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17489             for (int j=0; j<oomPss.length; j++) {
17490                 if (oomPss[j] != 0) {
17491                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17492                             : DUMP_MEM_OOM_LABEL[j];
17493                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17494                             DUMP_MEM_OOM_ADJ[j]);
17495                     item.subitems = oomProcs[j];
17496                     oomMems.add(item);
17497                 }
17498             }
17499
17500             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17501             if (!brief && !oomOnly && !isCompact) {
17502                 pw.println();
17503                 pw.println("Total PSS by process:");
17504                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17505                 pw.println();
17506             }
17507             if (!isCompact) {
17508                 pw.println("Total PSS by OOM adjustment:");
17509             }
17510             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17511             if (!brief && !oomOnly) {
17512                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17513                 if (!isCompact) {
17514                     out.println();
17515                     out.println("Total PSS by category:");
17516                 }
17517                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17518             }
17519             if (!isCompact) {
17520                 pw.println();
17521             }
17522             MemInfoReader memInfo = new MemInfoReader();
17523             memInfo.readMemInfo();
17524             if (nativeProcTotalPss > 0) {
17525                 synchronized (this) {
17526                     final long cachedKb = memInfo.getCachedSizeKb();
17527                     final long freeKb = memInfo.getFreeSizeKb();
17528                     final long zramKb = memInfo.getZramTotalSizeKb();
17529                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17530                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17531                             kernelKb*1024, nativeProcTotalPss*1024);
17532                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17533                             nativeProcTotalPss);
17534                 }
17535             }
17536             if (!brief) {
17537                 if (!isCompact) {
17538                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17539                     pw.print(" (status ");
17540                     switch (mLastMemoryLevel) {
17541                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17542                             pw.println("normal)");
17543                             break;
17544                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17545                             pw.println("moderate)");
17546                             break;
17547                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17548                             pw.println("low)");
17549                             break;
17550                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17551                             pw.println("critical)");
17552                             break;
17553                         default:
17554                             pw.print(mLastMemoryLevel);
17555                             pw.println(")");
17556                             break;
17557                     }
17558                     pw.print(" Free RAM: ");
17559                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17560                             + memInfo.getFreeSizeKb()));
17561                     pw.print(" (");
17562                     pw.print(stringifyKBSize(cachedPss));
17563                     pw.print(" cached pss + ");
17564                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17565                     pw.print(" cached kernel + ");
17566                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17567                     pw.println(" free)");
17568                 } else {
17569                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17570                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17571                             + memInfo.getFreeSizeKb()); pw.print(",");
17572                     pw.println(totalPss - cachedPss);
17573                 }
17574             }
17575             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17576                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17577                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17578             if (!isCompact) {
17579                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17580                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17581                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17582                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17583                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17584             } else {
17585                 pw.print("lostram,"); pw.println(lostRAM);
17586             }
17587             if (!brief) {
17588                 if (memInfo.getZramTotalSizeKb() != 0) {
17589                     if (!isCompact) {
17590                         pw.print("     ZRAM: ");
17591                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17592                                 pw.print(" physical used for ");
17593                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17594                                         - memInfo.getSwapFreeSizeKb()));
17595                                 pw.print(" in swap (");
17596                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17597                                 pw.println(" total swap)");
17598                     } else {
17599                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17600                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17601                                 pw.println(memInfo.getSwapFreeSizeKb());
17602                     }
17603                 }
17604                 final long[] ksm = getKsmInfo();
17605                 if (!isCompact) {
17606                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17607                             || ksm[KSM_VOLATILE] != 0) {
17608                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17609                                 pw.print(" saved from shared ");
17610                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17611                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17612                                 pw.print(" unshared; ");
17613                                 pw.print(stringifyKBSize(
17614                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17615                     }
17616                     pw.print("   Tuning: ");
17617                     pw.print(ActivityManager.staticGetMemoryClass());
17618                     pw.print(" (large ");
17619                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17620                     pw.print("), oom ");
17621                     pw.print(stringifySize(
17622                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17623                     pw.print(", restore limit ");
17624                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17625                     if (ActivityManager.isLowRamDeviceStatic()) {
17626                         pw.print(" (low-ram)");
17627                     }
17628                     if (ActivityManager.isHighEndGfx()) {
17629                         pw.print(" (high-end-gfx)");
17630                     }
17631                     pw.println();
17632                 } else {
17633                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17634                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17635                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17636                     pw.print("tuning,");
17637                     pw.print(ActivityManager.staticGetMemoryClass());
17638                     pw.print(',');
17639                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17640                     pw.print(',');
17641                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17642                     if (ActivityManager.isLowRamDeviceStatic()) {
17643                         pw.print(",low-ram");
17644                     }
17645                     if (ActivityManager.isHighEndGfx()) {
17646                         pw.print(",high-end-gfx");
17647                     }
17648                     pw.println();
17649                 }
17650             }
17651         }
17652     }
17653
17654     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17655             long memtrack, String name) {
17656         sb.append("  ");
17657         sb.append(ProcessList.makeOomAdjString(oomAdj));
17658         sb.append(' ');
17659         sb.append(ProcessList.makeProcStateString(procState));
17660         sb.append(' ');
17661         ProcessList.appendRamKb(sb, pss);
17662         sb.append(": ");
17663         sb.append(name);
17664         if (memtrack > 0) {
17665             sb.append(" (");
17666             sb.append(stringifyKBSize(memtrack));
17667             sb.append(" memtrack)");
17668         }
17669     }
17670
17671     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17672         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17673         sb.append(" (pid ");
17674         sb.append(mi.pid);
17675         sb.append(") ");
17676         sb.append(mi.adjType);
17677         sb.append('\n');
17678         if (mi.adjReason != null) {
17679             sb.append("                      ");
17680             sb.append(mi.adjReason);
17681             sb.append('\n');
17682         }
17683     }
17684
17685     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17686         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17687         for (int i=0, N=memInfos.size(); i<N; i++) {
17688             ProcessMemInfo mi = memInfos.get(i);
17689             infoMap.put(mi.pid, mi);
17690         }
17691         updateCpuStatsNow();
17692         long[] memtrackTmp = new long[1];
17693         final List<ProcessCpuTracker.Stats> stats;
17694         // Get a list of Stats that have vsize > 0
17695         synchronized (mProcessCpuTracker) {
17696             stats = mProcessCpuTracker.getStats((st) -> {
17697                 return st.vsize > 0;
17698             });
17699         }
17700         final int statsCount = stats.size();
17701         for (int i = 0; i < statsCount; i++) {
17702             ProcessCpuTracker.Stats st = stats.get(i);
17703             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17704             if (pss > 0) {
17705                 if (infoMap.indexOfKey(st.pid) < 0) {
17706                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17707                             ProcessList.NATIVE_ADJ, -1, "native", null);
17708                     mi.pss = pss;
17709                     mi.memtrack = memtrackTmp[0];
17710                     memInfos.add(mi);
17711                 }
17712             }
17713         }
17714
17715         long totalPss = 0;
17716         long totalMemtrack = 0;
17717         for (int i=0, N=memInfos.size(); i<N; i++) {
17718             ProcessMemInfo mi = memInfos.get(i);
17719             if (mi.pss == 0) {
17720                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17721                 mi.memtrack = memtrackTmp[0];
17722             }
17723             totalPss += mi.pss;
17724             totalMemtrack += mi.memtrack;
17725         }
17726         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17727             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17728                 if (lhs.oomAdj != rhs.oomAdj) {
17729                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17730                 }
17731                 if (lhs.pss != rhs.pss) {
17732                     return lhs.pss < rhs.pss ? 1 : -1;
17733                 }
17734                 return 0;
17735             }
17736         });
17737
17738         StringBuilder tag = new StringBuilder(128);
17739         StringBuilder stack = new StringBuilder(128);
17740         tag.append("Low on memory -- ");
17741         appendMemBucket(tag, totalPss, "total", false);
17742         appendMemBucket(stack, totalPss, "total", true);
17743
17744         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17745         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17746         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17747
17748         boolean firstLine = true;
17749         int lastOomAdj = Integer.MIN_VALUE;
17750         long extraNativeRam = 0;
17751         long extraNativeMemtrack = 0;
17752         long cachedPss = 0;
17753         for (int i=0, N=memInfos.size(); i<N; i++) {
17754             ProcessMemInfo mi = memInfos.get(i);
17755
17756             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17757                 cachedPss += mi.pss;
17758             }
17759
17760             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17761                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17762                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17763                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17764                 if (lastOomAdj != mi.oomAdj) {
17765                     lastOomAdj = mi.oomAdj;
17766                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17767                         tag.append(" / ");
17768                     }
17769                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17770                         if (firstLine) {
17771                             stack.append(":");
17772                             firstLine = false;
17773                         }
17774                         stack.append("\n\t at ");
17775                     } else {
17776                         stack.append("$");
17777                     }
17778                 } else {
17779                     tag.append(" ");
17780                     stack.append("$");
17781                 }
17782                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17783                     appendMemBucket(tag, mi.pss, mi.name, false);
17784                 }
17785                 appendMemBucket(stack, mi.pss, mi.name, true);
17786                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17787                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17788                     stack.append("(");
17789                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17790                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17791                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17792                             stack.append(":");
17793                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17794                         }
17795                     }
17796                     stack.append(")");
17797                 }
17798             }
17799
17800             appendMemInfo(fullNativeBuilder, mi);
17801             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17802                 // The short form only has native processes that are >= 512K.
17803                 if (mi.pss >= 512) {
17804                     appendMemInfo(shortNativeBuilder, mi);
17805                 } else {
17806                     extraNativeRam += mi.pss;
17807                     extraNativeMemtrack += mi.memtrack;
17808                 }
17809             } else {
17810                 // Short form has all other details, but if we have collected RAM
17811                 // from smaller native processes let's dump a summary of that.
17812                 if (extraNativeRam > 0) {
17813                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17814                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17815                     shortNativeBuilder.append('\n');
17816                     extraNativeRam = 0;
17817                 }
17818                 appendMemInfo(fullJavaBuilder, mi);
17819             }
17820         }
17821
17822         fullJavaBuilder.append("           ");
17823         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17824         fullJavaBuilder.append(": TOTAL");
17825         if (totalMemtrack > 0) {
17826             fullJavaBuilder.append(" (");
17827             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17828             fullJavaBuilder.append(" memtrack)");
17829         } else {
17830         }
17831         fullJavaBuilder.append("\n");
17832
17833         MemInfoReader memInfo = new MemInfoReader();
17834         memInfo.readMemInfo();
17835         final long[] infos = memInfo.getRawInfo();
17836
17837         StringBuilder memInfoBuilder = new StringBuilder(1024);
17838         Debug.getMemInfo(infos);
17839         memInfoBuilder.append("  MemInfo: ");
17840         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17841         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17842         memInfoBuilder.append(stringifyKBSize(
17843                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17844         memInfoBuilder.append(stringifyKBSize(
17845                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17846         memInfoBuilder.append(stringifyKBSize(
17847                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17848         memInfoBuilder.append("           ");
17849         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17850         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17851         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17852         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17853         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17854             memInfoBuilder.append("  ZRAM: ");
17855             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17856             memInfoBuilder.append(" RAM, ");
17857             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17858             memInfoBuilder.append(" swap total, ");
17859             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17860             memInfoBuilder.append(" swap free\n");
17861         }
17862         final long[] ksm = getKsmInfo();
17863         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17864                 || ksm[KSM_VOLATILE] != 0) {
17865             memInfoBuilder.append("  KSM: ");
17866             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17867             memInfoBuilder.append(" saved from shared ");
17868             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17869             memInfoBuilder.append("\n       ");
17870             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17871             memInfoBuilder.append(" unshared; ");
17872             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17873             memInfoBuilder.append(" volatile\n");
17874         }
17875         memInfoBuilder.append("  Free RAM: ");
17876         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17877                 + memInfo.getFreeSizeKb()));
17878         memInfoBuilder.append("\n");
17879         memInfoBuilder.append("  Used RAM: ");
17880         memInfoBuilder.append(stringifyKBSize(
17881                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17882         memInfoBuilder.append("\n");
17883         memInfoBuilder.append("  Lost RAM: ");
17884         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17885                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17886                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17887         memInfoBuilder.append("\n");
17888         Slog.i(TAG, "Low on memory:");
17889         Slog.i(TAG, shortNativeBuilder.toString());
17890         Slog.i(TAG, fullJavaBuilder.toString());
17891         Slog.i(TAG, memInfoBuilder.toString());
17892
17893         StringBuilder dropBuilder = new StringBuilder(1024);
17894         /*
17895         StringWriter oomSw = new StringWriter();
17896         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17897         StringWriter catSw = new StringWriter();
17898         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17899         String[] emptyArgs = new String[] { };
17900         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17901         oomPw.flush();
17902         String oomString = oomSw.toString();
17903         */
17904         dropBuilder.append("Low on memory:");
17905         dropBuilder.append(stack);
17906         dropBuilder.append('\n');
17907         dropBuilder.append(fullNativeBuilder);
17908         dropBuilder.append(fullJavaBuilder);
17909         dropBuilder.append('\n');
17910         dropBuilder.append(memInfoBuilder);
17911         dropBuilder.append('\n');
17912         /*
17913         dropBuilder.append(oomString);
17914         dropBuilder.append('\n');
17915         */
17916         StringWriter catSw = new StringWriter();
17917         synchronized (ActivityManagerService.this) {
17918             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17919             String[] emptyArgs = new String[] { };
17920             catPw.println();
17921             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17922             catPw.println();
17923             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17924                     false, null).dumpLocked();
17925             catPw.println();
17926             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17927             catPw.flush();
17928         }
17929         dropBuilder.append(catSw.toString());
17930         addErrorToDropBox("lowmem", null, "system_server", null,
17931                 null, tag.toString(), dropBuilder.toString(), null, null);
17932         //Slog.i(TAG, "Sent to dropbox:");
17933         //Slog.i(TAG, dropBuilder.toString());
17934         synchronized (ActivityManagerService.this) {
17935             long now = SystemClock.uptimeMillis();
17936             if (mLastMemUsageReportTime < now) {
17937                 mLastMemUsageReportTime = now;
17938             }
17939         }
17940     }
17941
17942     /**
17943      * Searches array of arguments for the specified string
17944      * @param args array of argument strings
17945      * @param value value to search for
17946      * @return true if the value is contained in the array
17947      */
17948     private static boolean scanArgs(String[] args, String value) {
17949         if (args != null) {
17950             for (String arg : args) {
17951                 if (value.equals(arg)) {
17952                     return true;
17953                 }
17954             }
17955         }
17956         return false;
17957     }
17958
17959     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17960             ContentProviderRecord cpr, boolean always) {
17961         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17962
17963         if (!inLaunching || always) {
17964             synchronized (cpr) {
17965                 cpr.launchingApp = null;
17966                 cpr.notifyAll();
17967             }
17968             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17969             String names[] = cpr.info.authority.split(";");
17970             for (int j = 0; j < names.length; j++) {
17971                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17972             }
17973         }
17974
17975         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17976             ContentProviderConnection conn = cpr.connections.get(i);
17977             if (conn.waiting) {
17978                 // If this connection is waiting for the provider, then we don't
17979                 // need to mess with its process unless we are always removing
17980                 // or for some reason the provider is not currently launching.
17981                 if (inLaunching && !always) {
17982                     continue;
17983                 }
17984             }
17985             ProcessRecord capp = conn.client;
17986             conn.dead = true;
17987             if (conn.stableCount > 0) {
17988                 if (!capp.persistent && capp.thread != null
17989                         && capp.pid != 0
17990                         && capp.pid != MY_PID) {
17991                     capp.kill("depends on provider "
17992                             + cpr.name.flattenToShortString()
17993                             + " in dying proc " + (proc != null ? proc.processName : "??")
17994                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17995                 }
17996             } else if (capp.thread != null && conn.provider.provider != null) {
17997                 try {
17998                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
17999                 } catch (RemoteException e) {
18000                 }
18001                 // In the protocol here, we don't expect the client to correctly
18002                 // clean up this connection, we'll just remove it.
18003                 cpr.connections.remove(i);
18004                 if (conn.client.conProviders.remove(conn)) {
18005                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18006                 }
18007             }
18008         }
18009
18010         if (inLaunching && always) {
18011             mLaunchingProviders.remove(cpr);
18012         }
18013         return inLaunching;
18014     }
18015
18016     /**
18017      * Main code for cleaning up a process when it has gone away.  This is
18018      * called both as a result of the process dying, or directly when stopping
18019      * a process when running in single process mode.
18020      *
18021      * @return Returns true if the given process has been restarted, so the
18022      * app that was passed in must remain on the process lists.
18023      */
18024     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18025             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18026         if (index >= 0) {
18027             removeLruProcessLocked(app);
18028             ProcessList.remove(app.pid);
18029         }
18030
18031         mProcessesToGc.remove(app);
18032         mPendingPssProcesses.remove(app);
18033
18034         // Dismiss any open dialogs.
18035         if (app.crashDialog != null && !app.forceCrashReport) {
18036             app.crashDialog.dismiss();
18037             app.crashDialog = null;
18038         }
18039         if (app.anrDialog != null) {
18040             app.anrDialog.dismiss();
18041             app.anrDialog = null;
18042         }
18043         if (app.waitDialog != null) {
18044             app.waitDialog.dismiss();
18045             app.waitDialog = null;
18046         }
18047
18048         app.crashing = false;
18049         app.notResponding = false;
18050
18051         app.resetPackageList(mProcessStats);
18052         app.unlinkDeathRecipient();
18053         app.makeInactive(mProcessStats);
18054         app.waitingToKill = null;
18055         app.forcingToImportant = null;
18056         updateProcessForegroundLocked(app, false, false);
18057         app.foregroundActivities = false;
18058         app.hasShownUi = false;
18059         app.treatLikeActivity = false;
18060         app.hasAboveClient = false;
18061         app.hasClientActivities = false;
18062
18063         mServices.killServicesLocked(app, allowRestart);
18064
18065         boolean restart = false;
18066
18067         // Remove published content providers.
18068         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18069             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18070             final boolean always = app.bad || !allowRestart;
18071             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18072             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18073                 // We left the provider in the launching list, need to
18074                 // restart it.
18075                 restart = true;
18076             }
18077
18078             cpr.provider = null;
18079             cpr.proc = null;
18080         }
18081         app.pubProviders.clear();
18082
18083         // Take care of any launching providers waiting for this process.
18084         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18085             restart = true;
18086         }
18087
18088         // Unregister from connected content providers.
18089         if (!app.conProviders.isEmpty()) {
18090             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18091                 ContentProviderConnection conn = app.conProviders.get(i);
18092                 conn.provider.connections.remove(conn);
18093                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18094                         conn.provider.name);
18095             }
18096             app.conProviders.clear();
18097         }
18098
18099         // At this point there may be remaining entries in mLaunchingProviders
18100         // where we were the only one waiting, so they are no longer of use.
18101         // Look for these and clean up if found.
18102         // XXX Commented out for now.  Trying to figure out a way to reproduce
18103         // the actual situation to identify what is actually going on.
18104         if (false) {
18105             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18106                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18107                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18108                     synchronized (cpr) {
18109                         cpr.launchingApp = null;
18110                         cpr.notifyAll();
18111                     }
18112                 }
18113             }
18114         }
18115
18116         skipCurrentReceiverLocked(app);
18117
18118         // Unregister any receivers.
18119         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18120             removeReceiverLocked(app.receivers.valueAt(i));
18121         }
18122         app.receivers.clear();
18123
18124         // If the app is undergoing backup, tell the backup manager about it
18125         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18126             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18127                     + mBackupTarget.appInfo + " died during backup");
18128             mHandler.post(new Runnable() {
18129                 @Override
18130                 public void run(){
18131                     try {
18132                         IBackupManager bm = IBackupManager.Stub.asInterface(
18133                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18134                         bm.agentDisconnected(app.info.packageName);
18135                     } catch (RemoteException e) {
18136                         // can't happen; backup manager is local
18137                     }
18138                 }
18139             });
18140         }
18141
18142         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18143             ProcessChangeItem item = mPendingProcessChanges.get(i);
18144             if (item.pid == app.pid) {
18145                 mPendingProcessChanges.remove(i);
18146                 mAvailProcessChanges.add(item);
18147             }
18148         }
18149         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18150                 null).sendToTarget();
18151
18152         // If the caller is restarting this app, then leave it in its
18153         // current lists and let the caller take care of it.
18154         if (restarting) {
18155             return false;
18156         }
18157
18158         if (!app.persistent || app.isolated) {
18159             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18160                     "Removing non-persistent process during cleanup: " + app);
18161             if (!replacingPid) {
18162                 removeProcessNameLocked(app.processName, app.uid, app);
18163             }
18164             if (mHeavyWeightProcess == app) {
18165                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18166                         mHeavyWeightProcess.userId, 0));
18167                 mHeavyWeightProcess = null;
18168             }
18169         } else if (!app.removed) {
18170             // This app is persistent, so we need to keep its record around.
18171             // If it is not already on the pending app list, add it there
18172             // and start a new process for it.
18173             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18174                 mPersistentStartingProcesses.add(app);
18175                 restart = true;
18176             }
18177         }
18178         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18179                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18180         mProcessesOnHold.remove(app);
18181
18182         if (app == mHomeProcess) {
18183             mHomeProcess = null;
18184         }
18185         if (app == mPreviousProcess) {
18186             mPreviousProcess = null;
18187         }
18188
18189         if (restart && !app.isolated) {
18190             // We have components that still need to be running in the
18191             // process, so re-launch it.
18192             if (index < 0) {
18193                 ProcessList.remove(app.pid);
18194             }
18195             addProcessNameLocked(app);
18196             startProcessLocked(app, "restart", app.processName);
18197             return true;
18198         } else if (app.pid > 0 && app.pid != MY_PID) {
18199             // Goodbye!
18200             boolean removed;
18201             synchronized (mPidsSelfLocked) {
18202                 mPidsSelfLocked.remove(app.pid);
18203                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18204             }
18205             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18206             if (app.isolated) {
18207                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18208             }
18209             app.setPid(0);
18210         }
18211         return false;
18212     }
18213
18214     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18215         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18216             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18217             if (cpr.launchingApp == app) {
18218                 return true;
18219             }
18220         }
18221         return false;
18222     }
18223
18224     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18225         // Look through the content providers we are waiting to have launched,
18226         // and if any run in this process then either schedule a restart of
18227         // the process or kill the client waiting for it if this process has
18228         // gone bad.
18229         boolean restart = false;
18230         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18231             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18232             if (cpr.launchingApp == app) {
18233                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18234                     restart = true;
18235                 } else {
18236                     removeDyingProviderLocked(app, cpr, true);
18237                 }
18238             }
18239         }
18240         return restart;
18241     }
18242
18243     // =========================================================
18244     // SERVICES
18245     // =========================================================
18246
18247     @Override
18248     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18249             int flags) {
18250         enforceNotIsolatedCaller("getServices");
18251
18252         final int callingUid = Binder.getCallingUid();
18253         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18254             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18255         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18256             callingUid);
18257         synchronized (this) {
18258             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18259                 allowed, canInteractAcrossUsers);
18260         }
18261     }
18262
18263     @Override
18264     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18265         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18266         synchronized (this) {
18267             return mServices.getRunningServiceControlPanelLocked(name);
18268         }
18269     }
18270
18271     @Override
18272     public ComponentName startService(IApplicationThread caller, Intent service,
18273             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18274             throws TransactionTooLargeException {
18275         enforceNotIsolatedCaller("startService");
18276         // Refuse possible leaked file descriptors
18277         if (service != null && service.hasFileDescriptors() == true) {
18278             throw new IllegalArgumentException("File descriptors passed in Intent");
18279         }
18280
18281         if (callingPackage == null) {
18282             throw new IllegalArgumentException("callingPackage cannot be null");
18283         }
18284
18285         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18286                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18287         synchronized(this) {
18288             final int callingPid = Binder.getCallingPid();
18289             final int callingUid = Binder.getCallingUid();
18290             final long origId = Binder.clearCallingIdentity();
18291             ComponentName res;
18292             try {
18293                 res = mServices.startServiceLocked(caller, service,
18294                         resolvedType, callingPid, callingUid,
18295                         requireForeground, callingPackage, userId);
18296             } finally {
18297                 Binder.restoreCallingIdentity(origId);
18298             }
18299             return res;
18300         }
18301     }
18302
18303     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18304             boolean fgRequired, String callingPackage, int userId)
18305             throws TransactionTooLargeException {
18306         synchronized(this) {
18307             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18308                     "startServiceInPackage: " + service + " type=" + resolvedType);
18309             final long origId = Binder.clearCallingIdentity();
18310             ComponentName res;
18311             try {
18312                 res = mServices.startServiceLocked(null, service,
18313                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18314             } finally {
18315                 Binder.restoreCallingIdentity(origId);
18316             }
18317             return res;
18318         }
18319     }
18320
18321     @Override
18322     public int stopService(IApplicationThread caller, Intent service,
18323             String resolvedType, int userId) {
18324         enforceNotIsolatedCaller("stopService");
18325         // Refuse possible leaked file descriptors
18326         if (service != null && service.hasFileDescriptors() == true) {
18327             throw new IllegalArgumentException("File descriptors passed in Intent");
18328         }
18329
18330         synchronized(this) {
18331             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18332         }
18333     }
18334
18335     @Override
18336     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18337         enforceNotIsolatedCaller("peekService");
18338         // Refuse possible leaked file descriptors
18339         if (service != null && service.hasFileDescriptors() == true) {
18340             throw new IllegalArgumentException("File descriptors passed in Intent");
18341         }
18342
18343         if (callingPackage == null) {
18344             throw new IllegalArgumentException("callingPackage cannot be null");
18345         }
18346
18347         synchronized(this) {
18348             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18349         }
18350     }
18351
18352     @Override
18353     public boolean stopServiceToken(ComponentName className, IBinder token,
18354             int startId) {
18355         synchronized(this) {
18356             return mServices.stopServiceTokenLocked(className, token, startId);
18357         }
18358     }
18359
18360     @Override
18361     public void setServiceForeground(ComponentName className, IBinder token,
18362             int id, Notification notification, int flags) {
18363         synchronized(this) {
18364             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18365         }
18366     }
18367
18368     @Override
18369     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18370             boolean requireFull, String name, String callerPackage) {
18371         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18372                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18373     }
18374
18375     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18376             String className, int flags) {
18377         boolean result = false;
18378         // For apps that don't have pre-defined UIDs, check for permission
18379         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18380             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18381                 if (ActivityManager.checkUidPermission(
18382                         INTERACT_ACROSS_USERS,
18383                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18384                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18385                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18386                             + " requests FLAG_SINGLE_USER, but app does not hold "
18387                             + INTERACT_ACROSS_USERS;
18388                     Slog.w(TAG, msg);
18389                     throw new SecurityException(msg);
18390                 }
18391                 // Permission passed
18392                 result = true;
18393             }
18394         } else if ("system".equals(componentProcessName)) {
18395             result = true;
18396         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18397             // Phone app and persistent apps are allowed to export singleuser providers.
18398             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18399                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18400         }
18401         if (DEBUG_MU) Slog.v(TAG_MU,
18402                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18403                 + Integer.toHexString(flags) + ") = " + result);
18404         return result;
18405     }
18406
18407     /**
18408      * Checks to see if the caller is in the same app as the singleton
18409      * component, or the component is in a special app. It allows special apps
18410      * to export singleton components but prevents exporting singleton
18411      * components for regular apps.
18412      */
18413     boolean isValidSingletonCall(int callingUid, int componentUid) {
18414         int componentAppId = UserHandle.getAppId(componentUid);
18415         return UserHandle.isSameApp(callingUid, componentUid)
18416                 || componentAppId == SYSTEM_UID
18417                 || componentAppId == PHONE_UID
18418                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18419                         == PackageManager.PERMISSION_GRANTED;
18420     }
18421
18422     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18423             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18424             int userId) throws TransactionTooLargeException {
18425         enforceNotIsolatedCaller("bindService");
18426
18427         // Refuse possible leaked file descriptors
18428         if (service != null && service.hasFileDescriptors() == true) {
18429             throw new IllegalArgumentException("File descriptors passed in Intent");
18430         }
18431
18432         if (callingPackage == null) {
18433             throw new IllegalArgumentException("callingPackage cannot be null");
18434         }
18435
18436         synchronized(this) {
18437             return mServices.bindServiceLocked(caller, token, service,
18438                     resolvedType, connection, flags, callingPackage, userId);
18439         }
18440     }
18441
18442     public boolean unbindService(IServiceConnection connection) {
18443         synchronized (this) {
18444             return mServices.unbindServiceLocked(connection);
18445         }
18446     }
18447
18448     public void publishService(IBinder token, Intent intent, IBinder service) {
18449         // Refuse possible leaked file descriptors
18450         if (intent != null && intent.hasFileDescriptors() == true) {
18451             throw new IllegalArgumentException("File descriptors passed in Intent");
18452         }
18453
18454         synchronized(this) {
18455             if (!(token instanceof ServiceRecord)) {
18456                 throw new IllegalArgumentException("Invalid service token");
18457             }
18458             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18459         }
18460     }
18461
18462     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18463         // Refuse possible leaked file descriptors
18464         if (intent != null && intent.hasFileDescriptors() == true) {
18465             throw new IllegalArgumentException("File descriptors passed in Intent");
18466         }
18467
18468         synchronized(this) {
18469             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18470         }
18471     }
18472
18473     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18474         synchronized(this) {
18475             if (!(token instanceof ServiceRecord)) {
18476                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18477                 throw new IllegalArgumentException("Invalid service token");
18478             }
18479             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18480         }
18481     }
18482
18483     // =========================================================
18484     // BACKUP AND RESTORE
18485     // =========================================================
18486
18487     // Cause the target app to be launched if necessary and its backup agent
18488     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18489     // activity manager to announce its creation.
18490     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18491         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18492         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18493
18494         IPackageManager pm = AppGlobals.getPackageManager();
18495         ApplicationInfo app = null;
18496         try {
18497             app = pm.getApplicationInfo(packageName, 0, userId);
18498         } catch (RemoteException e) {
18499             // can't happen; package manager is process-local
18500         }
18501         if (app == null) {
18502             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18503             return false;
18504         }
18505
18506         int oldBackupUid;
18507         int newBackupUid;
18508
18509         synchronized(this) {
18510             // !!! TODO: currently no check here that we're already bound
18511             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18512             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18513             synchronized (stats) {
18514                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18515             }
18516
18517             // Backup agent is now in use, its package can't be stopped.
18518             try {
18519                 AppGlobals.getPackageManager().setPackageStoppedState(
18520                         app.packageName, false, UserHandle.getUserId(app.uid));
18521             } catch (RemoteException e) {
18522             } catch (IllegalArgumentException e) {
18523                 Slog.w(TAG, "Failed trying to unstop package "
18524                         + app.packageName + ": " + e);
18525             }
18526
18527             BackupRecord r = new BackupRecord(ss, app, backupMode);
18528             ComponentName hostingName =
18529                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18530                             ? new ComponentName(app.packageName, app.backupAgentName)
18531                             : new ComponentName("android", "FullBackupAgent");
18532             // startProcessLocked() returns existing proc's record if it's already running
18533             ProcessRecord proc = startProcessLocked(app.processName, app,
18534                     false, 0, "backup", hostingName, false, false, false);
18535             if (proc == null) {
18536                 Slog.e(TAG, "Unable to start backup agent process " + r);
18537                 return false;
18538             }
18539
18540             // If the app is a regular app (uid >= 10000) and not the system server or phone
18541             // process, etc, then mark it as being in full backup so that certain calls to the
18542             // process can be blocked. This is not reset to false anywhere because we kill the
18543             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18544             if (UserHandle.isApp(app.uid) &&
18545                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18546                 proc.inFullBackup = true;
18547             }
18548             r.app = proc;
18549             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18550             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18551             mBackupTarget = r;
18552             mBackupAppName = app.packageName;
18553
18554             // Try not to kill the process during backup
18555             updateOomAdjLocked(proc, true);
18556
18557             // If the process is already attached, schedule the creation of the backup agent now.
18558             // If it is not yet live, this will be done when it attaches to the framework.
18559             if (proc.thread != null) {
18560                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18561                 try {
18562                     proc.thread.scheduleCreateBackupAgent(app,
18563                             compatibilityInfoForPackageLocked(app), backupMode);
18564                 } catch (RemoteException e) {
18565                     // Will time out on the backup manager side
18566                 }
18567             } else {
18568                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18569             }
18570             // Invariants: at this point, the target app process exists and the application
18571             // is either already running or in the process of coming up.  mBackupTarget and
18572             // mBackupAppName describe the app, so that when it binds back to the AM we
18573             // know that it's scheduled for a backup-agent operation.
18574         }
18575
18576         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18577         if (oldBackupUid != -1) {
18578             js.removeBackingUpUid(oldBackupUid);
18579         }
18580         if (newBackupUid != -1) {
18581             js.addBackingUpUid(newBackupUid);
18582         }
18583
18584         return true;
18585     }
18586
18587     @Override
18588     public void clearPendingBackup() {
18589         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18590         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18591
18592         synchronized (this) {
18593             mBackupTarget = null;
18594             mBackupAppName = null;
18595         }
18596
18597         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18598         js.clearAllBackingUpUids();
18599     }
18600
18601     // A backup agent has just come up
18602     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18603         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18604                 + " = " + agent);
18605
18606         synchronized(this) {
18607             if (!agentPackageName.equals(mBackupAppName)) {
18608                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18609                 return;
18610             }
18611         }
18612
18613         long oldIdent = Binder.clearCallingIdentity();
18614         try {
18615             IBackupManager bm = IBackupManager.Stub.asInterface(
18616                     ServiceManager.getService(Context.BACKUP_SERVICE));
18617             bm.agentConnected(agentPackageName, agent);
18618         } catch (RemoteException e) {
18619             // can't happen; the backup manager service is local
18620         } catch (Exception e) {
18621             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18622             e.printStackTrace();
18623         } finally {
18624             Binder.restoreCallingIdentity(oldIdent);
18625         }
18626     }
18627
18628     // done with this agent
18629     public void unbindBackupAgent(ApplicationInfo appInfo) {
18630         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18631         if (appInfo == null) {
18632             Slog.w(TAG, "unbind backup agent for null app");
18633             return;
18634         }
18635
18636         int oldBackupUid;
18637
18638         synchronized(this) {
18639             try {
18640                 if (mBackupAppName == null) {
18641                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18642                     return;
18643                 }
18644
18645                 if (!mBackupAppName.equals(appInfo.packageName)) {
18646                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18647                     return;
18648                 }
18649
18650                 // Not backing this app up any more; reset its OOM adjustment
18651                 final ProcessRecord proc = mBackupTarget.app;
18652                 updateOomAdjLocked(proc, true);
18653                 proc.inFullBackup = false;
18654
18655                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18656
18657                 // If the app crashed during backup, 'thread' will be null here
18658                 if (proc.thread != null) {
18659                     try {
18660                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18661                                 compatibilityInfoForPackageLocked(appInfo));
18662                     } catch (Exception e) {
18663                         Slog.e(TAG, "Exception when unbinding backup agent:");
18664                         e.printStackTrace();
18665                     }
18666                 }
18667             } finally {
18668                 mBackupTarget = null;
18669                 mBackupAppName = null;
18670             }
18671         }
18672
18673         if (oldBackupUid != -1) {
18674             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18675             js.removeBackingUpUid(oldBackupUid);
18676         }
18677     }
18678
18679     // =========================================================
18680     // BROADCASTS
18681     // =========================================================
18682
18683     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18684         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18685             return false;
18686         }
18687         // Easy case -- we have the app's ProcessRecord.
18688         if (record != null) {
18689             return record.info.isInstantApp();
18690         }
18691         // Otherwise check with PackageManager.
18692         if (callerPackage == null) {
18693             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18694             throw new IllegalArgumentException("Calling application did not provide package name");
18695         }
18696         mAppOpsService.checkPackage(uid, callerPackage);
18697         try {
18698             IPackageManager pm = AppGlobals.getPackageManager();
18699             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18700         } catch (RemoteException e) {
18701             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18702             return true;
18703         }
18704     }
18705
18706     boolean isPendingBroadcastProcessLocked(int pid) {
18707         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18708                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18709     }
18710
18711     void skipPendingBroadcastLocked(int pid) {
18712             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18713             for (BroadcastQueue queue : mBroadcastQueues) {
18714                 queue.skipPendingBroadcastLocked(pid);
18715             }
18716     }
18717
18718     // The app just attached; send any pending broadcasts that it should receive
18719     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18720         boolean didSomething = false;
18721         for (BroadcastQueue queue : mBroadcastQueues) {
18722             didSomething |= queue.sendPendingBroadcastsLocked(app);
18723         }
18724         return didSomething;
18725     }
18726
18727     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18728             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18729             int flags) {
18730         enforceNotIsolatedCaller("registerReceiver");
18731         ArrayList<Intent> stickyIntents = null;
18732         ProcessRecord callerApp = null;
18733         final boolean visibleToInstantApps
18734                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18735         int callingUid;
18736         int callingPid;
18737         boolean instantApp;
18738         synchronized(this) {
18739             if (caller != null) {
18740                 callerApp = getRecordForAppLocked(caller);
18741                 if (callerApp == null) {
18742                     throw new SecurityException(
18743                             "Unable to find app for caller " + caller
18744                             + " (pid=" + Binder.getCallingPid()
18745                             + ") when registering receiver " + receiver);
18746                 }
18747                 if (callerApp.info.uid != SYSTEM_UID &&
18748                         !callerApp.pkgList.containsKey(callerPackage) &&
18749                         !"android".equals(callerPackage)) {
18750                     throw new SecurityException("Given caller package " + callerPackage
18751                             + " is not running in process " + callerApp);
18752                 }
18753                 callingUid = callerApp.info.uid;
18754                 callingPid = callerApp.pid;
18755             } else {
18756                 callerPackage = null;
18757                 callingUid = Binder.getCallingUid();
18758                 callingPid = Binder.getCallingPid();
18759             }
18760
18761             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18762             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18763                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18764
18765             Iterator<String> actions = filter.actionsIterator();
18766             if (actions == null) {
18767                 ArrayList<String> noAction = new ArrayList<String>(1);
18768                 noAction.add(null);
18769                 actions = noAction.iterator();
18770             }
18771
18772             // Collect stickies of users
18773             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18774             while (actions.hasNext()) {
18775                 String action = actions.next();
18776                 for (int id : userIds) {
18777                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18778                     if (stickies != null) {
18779                         ArrayList<Intent> intents = stickies.get(action);
18780                         if (intents != null) {
18781                             if (stickyIntents == null) {
18782                                 stickyIntents = new ArrayList<Intent>();
18783                             }
18784                             stickyIntents.addAll(intents);
18785                         }
18786                     }
18787                 }
18788             }
18789         }
18790
18791         ArrayList<Intent> allSticky = null;
18792         if (stickyIntents != null) {
18793             final ContentResolver resolver = mContext.getContentResolver();
18794             // Look for any matching sticky broadcasts...
18795             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18796                 Intent intent = stickyIntents.get(i);
18797                 // Don't provided intents that aren't available to instant apps.
18798                 if (instantApp &&
18799                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18800                     continue;
18801                 }
18802                 // If intent has scheme "content", it will need to acccess
18803                 // provider that needs to lock mProviderMap in ActivityThread
18804                 // and also it may need to wait application response, so we
18805                 // cannot lock ActivityManagerService here.
18806                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18807                     if (allSticky == null) {
18808                         allSticky = new ArrayList<Intent>();
18809                     }
18810                     allSticky.add(intent);
18811                 }
18812             }
18813         }
18814
18815         // The first sticky in the list is returned directly back to the client.
18816         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18817         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18818         if (receiver == null) {
18819             return sticky;
18820         }
18821
18822         synchronized (this) {
18823             if (callerApp != null && (callerApp.thread == null
18824                     || callerApp.thread.asBinder() != caller.asBinder())) {
18825                 // Original caller already died
18826                 return null;
18827             }
18828             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18829             if (rl == null) {
18830                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18831                         userId, receiver);
18832                 if (rl.app != null) {
18833                     rl.app.receivers.add(rl);
18834                 } else {
18835                     try {
18836                         receiver.asBinder().linkToDeath(rl, 0);
18837                     } catch (RemoteException e) {
18838                         return sticky;
18839                     }
18840                     rl.linkedToDeath = true;
18841                 }
18842                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18843             } else if (rl.uid != callingUid) {
18844                 throw new IllegalArgumentException(
18845                         "Receiver requested to register for uid " + callingUid
18846                         + " was previously registered for uid " + rl.uid
18847                         + " callerPackage is " + callerPackage);
18848             } else if (rl.pid != callingPid) {
18849                 throw new IllegalArgumentException(
18850                         "Receiver requested to register for pid " + callingPid
18851                         + " was previously registered for pid " + rl.pid
18852                         + " callerPackage is " + callerPackage);
18853             } else if (rl.userId != userId) {
18854                 throw new IllegalArgumentException(
18855                         "Receiver requested to register for user " + userId
18856                         + " was previously registered for user " + rl.userId
18857                         + " callerPackage is " + callerPackage);
18858             }
18859             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18860                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18861             rl.add(bf);
18862             if (!bf.debugCheck()) {
18863                 Slog.w(TAG, "==> For Dynamic broadcast");
18864             }
18865             mReceiverResolver.addFilter(bf);
18866
18867             // Enqueue broadcasts for all existing stickies that match
18868             // this filter.
18869             if (allSticky != null) {
18870                 ArrayList receivers = new ArrayList();
18871                 receivers.add(bf);
18872
18873                 final int stickyCount = allSticky.size();
18874                 for (int i = 0; i < stickyCount; i++) {
18875                     Intent intent = allSticky.get(i);
18876                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18877                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18878                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18879                             null, 0, null, null, false, true, true, -1);
18880                     queue.enqueueParallelBroadcastLocked(r);
18881                     queue.scheduleBroadcastsLocked();
18882                 }
18883             }
18884
18885             return sticky;
18886         }
18887     }
18888
18889     public void unregisterReceiver(IIntentReceiver receiver) {
18890         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18891
18892         final long origId = Binder.clearCallingIdentity();
18893         try {
18894             boolean doTrim = false;
18895
18896             synchronized(this) {
18897                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18898                 if (rl != null) {
18899                     final BroadcastRecord r = rl.curBroadcast;
18900                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18901                         final boolean doNext = r.queue.finishReceiverLocked(
18902                                 r, r.resultCode, r.resultData, r.resultExtras,
18903                                 r.resultAbort, false);
18904                         if (doNext) {
18905                             doTrim = true;
18906                             r.queue.processNextBroadcast(false);
18907                         }
18908                     }
18909
18910                     if (rl.app != null) {
18911                         rl.app.receivers.remove(rl);
18912                     }
18913                     removeReceiverLocked(rl);
18914                     if (rl.linkedToDeath) {
18915                         rl.linkedToDeath = false;
18916                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18917                     }
18918                 }
18919             }
18920
18921             // If we actually concluded any broadcasts, we might now be able
18922             // to trim the recipients' apps from our working set
18923             if (doTrim) {
18924                 trimApplications();
18925                 return;
18926             }
18927
18928         } finally {
18929             Binder.restoreCallingIdentity(origId);
18930         }
18931     }
18932
18933     void removeReceiverLocked(ReceiverList rl) {
18934         mRegisteredReceivers.remove(rl.receiver.asBinder());
18935         for (int i = rl.size() - 1; i >= 0; i--) {
18936             mReceiverResolver.removeFilter(rl.get(i));
18937         }
18938     }
18939
18940     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18941         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18942             ProcessRecord r = mLruProcesses.get(i);
18943             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18944                 try {
18945                     r.thread.dispatchPackageBroadcast(cmd, packages);
18946                 } catch (RemoteException ex) {
18947                 }
18948             }
18949         }
18950     }
18951
18952     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18953             int callingUid, int[] users) {
18954         // TODO: come back and remove this assumption to triage all broadcasts
18955         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18956
18957         List<ResolveInfo> receivers = null;
18958         try {
18959             HashSet<ComponentName> singleUserReceivers = null;
18960             boolean scannedFirstReceivers = false;
18961             for (int user : users) {
18962                 // Skip users that have Shell restrictions, with exception of always permitted
18963                 // Shell broadcasts
18964                 if (callingUid == SHELL_UID
18965                         && mUserController.hasUserRestriction(
18966                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18967                         && !isPermittedShellBroadcast(intent)) {
18968                     continue;
18969                 }
18970                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18971                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18972                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18973                     // If this is not the system user, we need to check for
18974                     // any receivers that should be filtered out.
18975                     for (int i=0; i<newReceivers.size(); i++) {
18976                         ResolveInfo ri = newReceivers.get(i);
18977                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18978                             newReceivers.remove(i);
18979                             i--;
18980                         }
18981                     }
18982                 }
18983                 if (newReceivers != null && newReceivers.size() == 0) {
18984                     newReceivers = null;
18985                 }
18986                 if (receivers == null) {
18987                     receivers = newReceivers;
18988                 } else if (newReceivers != null) {
18989                     // We need to concatenate the additional receivers
18990                     // found with what we have do far.  This would be easy,
18991                     // but we also need to de-dup any receivers that are
18992                     // singleUser.
18993                     if (!scannedFirstReceivers) {
18994                         // Collect any single user receivers we had already retrieved.
18995                         scannedFirstReceivers = true;
18996                         for (int i=0; i<receivers.size(); i++) {
18997                             ResolveInfo ri = receivers.get(i);
18998                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
18999                                 ComponentName cn = new ComponentName(
19000                                         ri.activityInfo.packageName, ri.activityInfo.name);
19001                                 if (singleUserReceivers == null) {
19002                                     singleUserReceivers = new HashSet<ComponentName>();
19003                                 }
19004                                 singleUserReceivers.add(cn);
19005                             }
19006                         }
19007                     }
19008                     // Add the new results to the existing results, tracking
19009                     // and de-dupping single user receivers.
19010                     for (int i=0; i<newReceivers.size(); i++) {
19011                         ResolveInfo ri = newReceivers.get(i);
19012                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19013                             ComponentName cn = new ComponentName(
19014                                     ri.activityInfo.packageName, ri.activityInfo.name);
19015                             if (singleUserReceivers == null) {
19016                                 singleUserReceivers = new HashSet<ComponentName>();
19017                             }
19018                             if (!singleUserReceivers.contains(cn)) {
19019                                 singleUserReceivers.add(cn);
19020                                 receivers.add(ri);
19021                             }
19022                         } else {
19023                             receivers.add(ri);
19024                         }
19025                     }
19026                 }
19027             }
19028         } catch (RemoteException ex) {
19029             // pm is in same process, this will never happen.
19030         }
19031         return receivers;
19032     }
19033
19034     private boolean isPermittedShellBroadcast(Intent intent) {
19035         // remote bugreport should always be allowed to be taken
19036         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19037     }
19038
19039     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19040             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19041         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19042             // Don't yell about broadcasts sent via shell
19043             return;
19044         }
19045
19046         final String action = intent.getAction();
19047         if (isProtectedBroadcast
19048                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19049                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19050                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19051                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19052                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19053                 || Intent.ACTION_MASTER_CLEAR.equals(action)
19054                 || Intent.ACTION_FACTORY_RESET.equals(action)
19055                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19056                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19057                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19058                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19059                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19060                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19061                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19062             // Broadcast is either protected, or it's a public action that
19063             // we've relaxed, so it's fine for system internals to send.
19064             return;
19065         }
19066
19067         // This broadcast may be a problem...  but there are often system components that
19068         // want to send an internal broadcast to themselves, which is annoying to have to
19069         // explicitly list each action as a protected broadcast, so we will check for that
19070         // one safe case and allow it: an explicit broadcast, only being received by something
19071         // that has protected itself.
19072         if (receivers != null && receivers.size() > 0
19073                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19074             boolean allProtected = true;
19075             for (int i = receivers.size()-1; i >= 0; i--) {
19076                 Object target = receivers.get(i);
19077                 if (target instanceof ResolveInfo) {
19078                     ResolveInfo ri = (ResolveInfo)target;
19079                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19080                         allProtected = false;
19081                         break;
19082                     }
19083                 } else {
19084                     BroadcastFilter bf = (BroadcastFilter)target;
19085                     if (bf.requiredPermission == null) {
19086                         allProtected = false;
19087                         break;
19088                     }
19089                 }
19090             }
19091             if (allProtected) {
19092                 // All safe!
19093                 return;
19094             }
19095         }
19096
19097         // The vast majority of broadcasts sent from system internals
19098         // should be protected to avoid security holes, so yell loudly
19099         // to ensure we examine these cases.
19100         if (callerApp != null) {
19101             Log.wtf(TAG, "Sending non-protected broadcast " + action
19102                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19103                     new Throwable());
19104         } else {
19105             Log.wtf(TAG, "Sending non-protected broadcast " + action
19106                             + " from system uid " + UserHandle.formatUid(callingUid)
19107                             + " pkg " + callerPackage,
19108                     new Throwable());
19109         }
19110     }
19111
19112     final int broadcastIntentLocked(ProcessRecord callerApp,
19113             String callerPackage, Intent intent, String resolvedType,
19114             IIntentReceiver resultTo, int resultCode, String resultData,
19115             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19116             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19117         intent = new Intent(intent);
19118
19119         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19120         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19121         if (callerInstantApp) {
19122             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19123         }
19124
19125         // By default broadcasts do not go to stopped apps.
19126         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19127
19128         // If we have not finished booting, don't allow this to launch new processes.
19129         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19130             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19131         }
19132
19133         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19134                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19135                 + " ordered=" + ordered + " userid=" + userId);
19136         if ((resultTo != null) && !ordered) {
19137             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19138         }
19139
19140         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19141                 ALLOW_NON_FULL, "broadcast", callerPackage);
19142
19143         // Make sure that the user who is receiving this broadcast is running.
19144         // If not, we will just skip it. Make an exception for shutdown broadcasts
19145         // and upgrade steps.
19146
19147         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19148             if ((callingUid != SYSTEM_UID
19149                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19150                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19151                 Slog.w(TAG, "Skipping broadcast of " + intent
19152                         + ": user " + userId + " is stopped");
19153                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19154             }
19155         }
19156
19157         BroadcastOptions brOptions = null;
19158         if (bOptions != null) {
19159             brOptions = new BroadcastOptions(bOptions);
19160             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19161                 // See if the caller is allowed to do this.  Note we are checking against
19162                 // the actual real caller (not whoever provided the operation as say a
19163                 // PendingIntent), because that who is actually supplied the arguments.
19164                 if (checkComponentPermission(
19165                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19166                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19167                         != PackageManager.PERMISSION_GRANTED) {
19168                     String msg = "Permission Denial: " + intent.getAction()
19169                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19170                             + ", uid=" + callingUid + ")"
19171                             + " requires "
19172                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19173                     Slog.w(TAG, msg);
19174                     throw new SecurityException(msg);
19175                 }
19176             }
19177         }
19178
19179         // Verify that protected broadcasts are only being sent by system code,
19180         // and that system code is only sending protected broadcasts.
19181         final String action = intent.getAction();
19182         final boolean isProtectedBroadcast;
19183         try {
19184             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19185         } catch (RemoteException e) {
19186             Slog.w(TAG, "Remote exception", e);
19187             return ActivityManager.BROADCAST_SUCCESS;
19188         }
19189
19190         final boolean isCallerSystem;
19191         switch (UserHandle.getAppId(callingUid)) {
19192             case ROOT_UID:
19193             case SYSTEM_UID:
19194             case PHONE_UID:
19195             case BLUETOOTH_UID:
19196             case NFC_UID:
19197                 isCallerSystem = true;
19198                 break;
19199             default:
19200                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19201                 break;
19202         }
19203
19204         // First line security check before anything else: stop non-system apps from
19205         // sending protected broadcasts.
19206         if (!isCallerSystem) {
19207             if (isProtectedBroadcast) {
19208                 String msg = "Permission Denial: not allowed to send broadcast "
19209                         + action + " from pid="
19210                         + callingPid + ", uid=" + callingUid;
19211                 Slog.w(TAG, msg);
19212                 throw new SecurityException(msg);
19213
19214             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19215                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19216                 // Special case for compatibility: we don't want apps to send this,
19217                 // but historically it has not been protected and apps may be using it
19218                 // to poke their own app widget.  So, instead of making it protected,
19219                 // just limit it to the caller.
19220                 if (callerPackage == null) {
19221                     String msg = "Permission Denial: not allowed to send broadcast "
19222                             + action + " from unknown caller.";
19223                     Slog.w(TAG, msg);
19224                     throw new SecurityException(msg);
19225                 } else if (intent.getComponent() != null) {
19226                     // They are good enough to send to an explicit component...  verify
19227                     // it is being sent to the calling app.
19228                     if (!intent.getComponent().getPackageName().equals(
19229                             callerPackage)) {
19230                         String msg = "Permission Denial: not allowed to send broadcast "
19231                                 + action + " to "
19232                                 + intent.getComponent().getPackageName() + " from "
19233                                 + callerPackage;
19234                         Slog.w(TAG, msg);
19235                         throw new SecurityException(msg);
19236                     }
19237                 } else {
19238                     // Limit broadcast to their own package.
19239                     intent.setPackage(callerPackage);
19240                 }
19241             }
19242         }
19243
19244         if (action != null) {
19245             if (getBackgroundLaunchBroadcasts().contains(action)) {
19246                 if (DEBUG_BACKGROUND_CHECK) {
19247                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19248                 }
19249                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19250             }
19251
19252             switch (action) {
19253                 case Intent.ACTION_UID_REMOVED:
19254                 case Intent.ACTION_PACKAGE_REMOVED:
19255                 case Intent.ACTION_PACKAGE_CHANGED:
19256                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19257                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19258                 case Intent.ACTION_PACKAGES_SUSPENDED:
19259                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19260                     // Handle special intents: if this broadcast is from the package
19261                     // manager about a package being removed, we need to remove all of
19262                     // its activities from the history stack.
19263                     if (checkComponentPermission(
19264                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19265                             callingPid, callingUid, -1, true)
19266                             != PackageManager.PERMISSION_GRANTED) {
19267                         String msg = "Permission Denial: " + intent.getAction()
19268                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19269                                 + ", uid=" + callingUid + ")"
19270                                 + " requires "
19271                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19272                         Slog.w(TAG, msg);
19273                         throw new SecurityException(msg);
19274                     }
19275                     switch (action) {
19276                         case Intent.ACTION_UID_REMOVED:
19277                             final int uid = getUidFromIntent(intent);
19278                             if (uid >= 0) {
19279                                 mBatteryStatsService.removeUid(uid);
19280                                 mAppOpsService.uidRemoved(uid);
19281                             }
19282                             break;
19283                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19284                             // If resources are unavailable just force stop all those packages
19285                             // and flush the attribute cache as well.
19286                             String list[] =
19287                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19288                             if (list != null && list.length > 0) {
19289                                 for (int i = 0; i < list.length; i++) {
19290                                     forceStopPackageLocked(list[i], -1, false, true, true,
19291                                             false, false, userId, "storage unmount");
19292                                 }
19293                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19294                                 sendPackageBroadcastLocked(
19295                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19296                                         list, userId);
19297                             }
19298                             break;
19299                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19300                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19301                             break;
19302                         case Intent.ACTION_PACKAGE_REMOVED:
19303                         case Intent.ACTION_PACKAGE_CHANGED:
19304                             Uri data = intent.getData();
19305                             String ssp;
19306                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19307                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19308                                 final boolean replacing =
19309                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19310                                 final boolean killProcess =
19311                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19312                                 final boolean fullUninstall = removed && !replacing;
19313                                 if (removed) {
19314                                     if (killProcess) {
19315                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19316                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19317                                                 false, true, true, false, fullUninstall, userId,
19318                                                 removed ? "pkg removed" : "pkg changed");
19319                                     }
19320                                     final int cmd = killProcess
19321                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19322                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19323                                     sendPackageBroadcastLocked(cmd,
19324                                             new String[] {ssp}, userId);
19325                                     if (fullUninstall) {
19326                                         mAppOpsService.packageRemoved(
19327                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19328
19329                                         // Remove all permissions granted from/to this package
19330                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19331
19332                                         removeTasksByPackageNameLocked(ssp, userId);
19333
19334                                         mServices.forceStopPackageLocked(ssp, userId);
19335
19336                                         // Hide the "unsupported display" dialog if necessary.
19337                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19338                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19339                                             mUnsupportedDisplaySizeDialog.dismiss();
19340                                             mUnsupportedDisplaySizeDialog = null;
19341                                         }
19342                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19343                                         mBatteryStatsService.notePackageUninstalled(ssp);
19344                                     }
19345                                 } else {
19346                                     if (killProcess) {
19347                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19348                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19349                                                 userId, ProcessList.INVALID_ADJ,
19350                                                 false, true, true, false, "change " + ssp);
19351                                     }
19352                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19353                                             intent.getStringArrayExtra(
19354                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19355                                 }
19356                             }
19357                             break;
19358                         case Intent.ACTION_PACKAGES_SUSPENDED:
19359                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19360                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19361                                     intent.getAction());
19362                             final String[] packageNames = intent.getStringArrayExtra(
19363                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19364                             final int userHandle = intent.getIntExtra(
19365                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19366
19367                             synchronized(ActivityManagerService.this) {
19368                                 mRecentTasks.onPackagesSuspendedChanged(
19369                                         packageNames, suspended, userHandle);
19370                             }
19371                             break;
19372                     }
19373                     break;
19374                 case Intent.ACTION_PACKAGE_REPLACED:
19375                 {
19376                     final Uri data = intent.getData();
19377                     final String ssp;
19378                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19379                         ApplicationInfo aInfo = null;
19380                         try {
19381                             aInfo = AppGlobals.getPackageManager()
19382                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19383                         } catch (RemoteException ignore) {}
19384                         if (aInfo == null) {
19385                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19386                                     + " ssp=" + ssp + " data=" + data);
19387                             return ActivityManager.BROADCAST_SUCCESS;
19388                         }
19389                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19390                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19391                                 new String[] {ssp}, userId);
19392                     }
19393                     break;
19394                 }
19395                 case Intent.ACTION_PACKAGE_ADDED:
19396                 {
19397                     // Special case for adding a package: by default turn on compatibility mode.
19398                     Uri data = intent.getData();
19399                     String ssp;
19400                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19401                         final boolean replacing =
19402                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19403                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19404
19405                         try {
19406                             ApplicationInfo ai = AppGlobals.getPackageManager().
19407                                     getApplicationInfo(ssp, 0, 0);
19408                             mBatteryStatsService.notePackageInstalled(ssp,
19409                                     ai != null ? ai.versionCode : 0);
19410                         } catch (RemoteException e) {
19411                         }
19412                     }
19413                     break;
19414                 }
19415                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19416                 {
19417                     Uri data = intent.getData();
19418                     String ssp;
19419                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19420                         // Hide the "unsupported display" dialog if necessary.
19421                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19422                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19423                             mUnsupportedDisplaySizeDialog.dismiss();
19424                             mUnsupportedDisplaySizeDialog = null;
19425                         }
19426                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19427                     }
19428                     break;
19429                 }
19430                 case Intent.ACTION_TIMEZONE_CHANGED:
19431                     // If this is the time zone changed action, queue up a message that will reset
19432                     // the timezone of all currently running processes. This message will get
19433                     // queued up before the broadcast happens.
19434                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19435                     break;
19436                 case Intent.ACTION_TIME_CHANGED:
19437                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19438                     // the tri-state value it may contain and "unknown".
19439                     // For convenience we re-use the Intent extra values.
19440                     final int NO_EXTRA_VALUE_FOUND = -1;
19441                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19442                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19443                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19444                     // Only send a message if the time preference is available.
19445                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19446                         Message updateTimePreferenceMsg =
19447                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19448                                         timeFormatPreferenceMsgValue, 0);
19449                         mHandler.sendMessage(updateTimePreferenceMsg);
19450                     }
19451                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19452                     synchronized (stats) {
19453                         stats.noteCurrentTimeChangedLocked();
19454                     }
19455                     break;
19456                 case Intent.ACTION_CLEAR_DNS_CACHE:
19457                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19458                     break;
19459                 case Proxy.PROXY_CHANGE_ACTION:
19460                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19461                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19462                     break;
19463                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19464                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19465                     // In N we just turned these off; in O we are turing them back on partly,
19466                     // only for registered receivers.  This will still address the main problem
19467                     // (a spam of apps waking up when a picture is taken putting significant
19468                     // memory pressure on the system at a bad point), while still allowing apps
19469                     // that are already actively running to know about this happening.
19470                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19471                     break;
19472                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19473                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19474                     break;
19475                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19476                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19477                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19478                     Log.w(TAG, "Broadcast " + action
19479                             + " no longer supported. It will not be delivered.");
19480                     return ActivityManager.BROADCAST_SUCCESS;
19481             }
19482
19483             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19484                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19485                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19486                 final int uid = getUidFromIntent(intent);
19487                 if (uid != -1) {
19488                     final UidRecord uidRec = mActiveUids.get(uid);
19489                     if (uidRec != null) {
19490                         uidRec.updateHasInternetPermission();
19491                     }
19492                 }
19493             }
19494         }
19495
19496         // Add to the sticky list if requested.
19497         if (sticky) {
19498             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19499                     callingPid, callingUid)
19500                     != PackageManager.PERMISSION_GRANTED) {
19501                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19502                         + callingPid + ", uid=" + callingUid
19503                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19504                 Slog.w(TAG, msg);
19505                 throw new SecurityException(msg);
19506             }
19507             if (requiredPermissions != null && requiredPermissions.length > 0) {
19508                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19509                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19510                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19511             }
19512             if (intent.getComponent() != null) {
19513                 throw new SecurityException(
19514                         "Sticky broadcasts can't target a specific component");
19515             }
19516             // We use userId directly here, since the "all" target is maintained
19517             // as a separate set of sticky broadcasts.
19518             if (userId != UserHandle.USER_ALL) {
19519                 // But first, if this is not a broadcast to all users, then
19520                 // make sure it doesn't conflict with an existing broadcast to
19521                 // all users.
19522                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19523                         UserHandle.USER_ALL);
19524                 if (stickies != null) {
19525                     ArrayList<Intent> list = stickies.get(intent.getAction());
19526                     if (list != null) {
19527                         int N = list.size();
19528                         int i;
19529                         for (i=0; i<N; i++) {
19530                             if (intent.filterEquals(list.get(i))) {
19531                                 throw new IllegalArgumentException(
19532                                         "Sticky broadcast " + intent + " for user "
19533                                         + userId + " conflicts with existing global broadcast");
19534                             }
19535                         }
19536                     }
19537                 }
19538             }
19539             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19540             if (stickies == null) {
19541                 stickies = new ArrayMap<>();
19542                 mStickyBroadcasts.put(userId, stickies);
19543             }
19544             ArrayList<Intent> list = stickies.get(intent.getAction());
19545             if (list == null) {
19546                 list = new ArrayList<>();
19547                 stickies.put(intent.getAction(), list);
19548             }
19549             final int stickiesCount = list.size();
19550             int i;
19551             for (i = 0; i < stickiesCount; i++) {
19552                 if (intent.filterEquals(list.get(i))) {
19553                     // This sticky already exists, replace it.
19554                     list.set(i, new Intent(intent));
19555                     break;
19556                 }
19557             }
19558             if (i >= stickiesCount) {
19559                 list.add(new Intent(intent));
19560             }
19561         }
19562
19563         int[] users;
19564         if (userId == UserHandle.USER_ALL) {
19565             // Caller wants broadcast to go to all started users.
19566             users = mUserController.getStartedUserArrayLocked();
19567         } else {
19568             // Caller wants broadcast to go to one specific user.
19569             users = new int[] {userId};
19570         }
19571
19572         // Figure out who all will receive this broadcast.
19573         List receivers = null;
19574         List<BroadcastFilter> registeredReceivers = null;
19575         // Need to resolve the intent to interested receivers...
19576         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19577                  == 0) {
19578             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19579         }
19580         if (intent.getComponent() == null) {
19581             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19582                 // Query one target user at a time, excluding shell-restricted users
19583                 for (int i = 0; i < users.length; i++) {
19584                     if (mUserController.hasUserRestriction(
19585                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19586                         continue;
19587                     }
19588                     List<BroadcastFilter> registeredReceiversForUser =
19589                             mReceiverResolver.queryIntent(intent,
19590                                     resolvedType, false /*defaultOnly*/, users[i]);
19591                     if (registeredReceivers == null) {
19592                         registeredReceivers = registeredReceiversForUser;
19593                     } else if (registeredReceiversForUser != null) {
19594                         registeredReceivers.addAll(registeredReceiversForUser);
19595                     }
19596                 }
19597             } else {
19598                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19599                         resolvedType, false /*defaultOnly*/, userId);
19600             }
19601         }
19602
19603         final boolean replacePending =
19604                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19605
19606         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19607                 + " replacePending=" + replacePending);
19608
19609         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19610         if (!ordered && NR > 0) {
19611             // If we are not serializing this broadcast, then send the
19612             // registered receivers separately so they don't wait for the
19613             // components to be launched.
19614             if (isCallerSystem) {
19615                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19616                         isProtectedBroadcast, registeredReceivers);
19617             }
19618             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19619             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19620                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19621                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19622                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19623             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19624             final boolean replaced = replacePending
19625                     && (queue.replaceParallelBroadcastLocked(r) != null);
19626             // Note: We assume resultTo is null for non-ordered broadcasts.
19627             if (!replaced) {
19628                 queue.enqueueParallelBroadcastLocked(r);
19629                 queue.scheduleBroadcastsLocked();
19630             }
19631             registeredReceivers = null;
19632             NR = 0;
19633         }
19634
19635         // Merge into one list.
19636         int ir = 0;
19637         if (receivers != null) {
19638             // A special case for PACKAGE_ADDED: do not allow the package
19639             // being added to see this broadcast.  This prevents them from
19640             // using this as a back door to get run as soon as they are
19641             // installed.  Maybe in the future we want to have a special install
19642             // broadcast or such for apps, but we'd like to deliberately make
19643             // this decision.
19644             String skipPackages[] = null;
19645             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19646                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19647                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19648                 Uri data = intent.getData();
19649                 if (data != null) {
19650                     String pkgName = data.getSchemeSpecificPart();
19651                     if (pkgName != null) {
19652                         skipPackages = new String[] { pkgName };
19653                     }
19654                 }
19655             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19656                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19657             }
19658             if (skipPackages != null && (skipPackages.length > 0)) {
19659                 for (String skipPackage : skipPackages) {
19660                     if (skipPackage != null) {
19661                         int NT = receivers.size();
19662                         for (int it=0; it<NT; it++) {
19663                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19664                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19665                                 receivers.remove(it);
19666                                 it--;
19667                                 NT--;
19668                             }
19669                         }
19670                     }
19671                 }
19672             }
19673
19674             int NT = receivers != null ? receivers.size() : 0;
19675             int it = 0;
19676             ResolveInfo curt = null;
19677             BroadcastFilter curr = null;
19678             while (it < NT && ir < NR) {
19679                 if (curt == null) {
19680                     curt = (ResolveInfo)receivers.get(it);
19681                 }
19682                 if (curr == null) {
19683                     curr = registeredReceivers.get(ir);
19684                 }
19685                 if (curr.getPriority() >= curt.priority) {
19686                     // Insert this broadcast record into the final list.
19687                     receivers.add(it, curr);
19688                     ir++;
19689                     curr = null;
19690                     it++;
19691                     NT++;
19692                 } else {
19693                     // Skip to the next ResolveInfo in the final list.
19694                     it++;
19695                     curt = null;
19696                 }
19697             }
19698         }
19699         while (ir < NR) {
19700             if (receivers == null) {
19701                 receivers = new ArrayList();
19702             }
19703             receivers.add(registeredReceivers.get(ir));
19704             ir++;
19705         }
19706
19707         if (isCallerSystem) {
19708             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19709                     isProtectedBroadcast, receivers);
19710         }
19711
19712         if ((receivers != null && receivers.size() > 0)
19713                 || resultTo != null) {
19714             BroadcastQueue queue = broadcastQueueForIntent(intent);
19715             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19716                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19717                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19718                     resultData, resultExtras, ordered, sticky, false, userId);
19719
19720             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19721                     + ": prev had " + queue.mOrderedBroadcasts.size());
19722             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19723                     "Enqueueing broadcast " + r.intent.getAction());
19724
19725             final BroadcastRecord oldRecord =
19726                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19727             if (oldRecord != null) {
19728                 // Replaced, fire the result-to receiver.
19729                 if (oldRecord.resultTo != null) {
19730                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19731                     try {
19732                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19733                                 oldRecord.intent,
19734                                 Activity.RESULT_CANCELED, null, null,
19735                                 false, false, oldRecord.userId);
19736                     } catch (RemoteException e) {
19737                         Slog.w(TAG, "Failure ["
19738                                 + queue.mQueueName + "] sending broadcast result of "
19739                                 + intent, e);
19740
19741                     }
19742                 }
19743             } else {
19744                 queue.enqueueOrderedBroadcastLocked(r);
19745                 queue.scheduleBroadcastsLocked();
19746             }
19747         } else {
19748             // There was nobody interested in the broadcast, but we still want to record
19749             // that it happened.
19750             if (intent.getComponent() == null && intent.getPackage() == null
19751                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19752                 // This was an implicit broadcast... let's record it for posterity.
19753                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19754             }
19755         }
19756
19757         return ActivityManager.BROADCAST_SUCCESS;
19758     }
19759
19760     /**
19761      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19762      */
19763     private int getUidFromIntent(Intent intent) {
19764         if (intent == null) {
19765             return -1;
19766         }
19767         final Bundle intentExtras = intent.getExtras();
19768         return intent.hasExtra(Intent.EXTRA_UID)
19769                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19770     }
19771
19772     final void rotateBroadcastStatsIfNeededLocked() {
19773         final long now = SystemClock.elapsedRealtime();
19774         if (mCurBroadcastStats == null ||
19775                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19776             mLastBroadcastStats = mCurBroadcastStats;
19777             if (mLastBroadcastStats != null) {
19778                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19779                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19780             }
19781             mCurBroadcastStats = new BroadcastStats();
19782         }
19783     }
19784
19785     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19786             int skipCount, long dispatchTime) {
19787         rotateBroadcastStatsIfNeededLocked();
19788         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19789     }
19790
19791     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19792         rotateBroadcastStatsIfNeededLocked();
19793         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19794     }
19795
19796     final Intent verifyBroadcastLocked(Intent intent) {
19797         // Refuse possible leaked file descriptors
19798         if (intent != null && intent.hasFileDescriptors() == true) {
19799             throw new IllegalArgumentException("File descriptors passed in Intent");
19800         }
19801
19802         int flags = intent.getFlags();
19803
19804         if (!mProcessesReady) {
19805             // if the caller really truly claims to know what they're doing, go
19806             // ahead and allow the broadcast without launching any receivers
19807             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19808                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19809             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19810                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19811                         + " before boot completion");
19812                 throw new IllegalStateException("Cannot broadcast before boot completed");
19813             }
19814         }
19815
19816         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19817             throw new IllegalArgumentException(
19818                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19819         }
19820
19821         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19822             switch (Binder.getCallingUid()) {
19823                 case ROOT_UID:
19824                 case SHELL_UID:
19825                     break;
19826                 default:
19827                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19828                             + Binder.getCallingUid());
19829                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19830                     break;
19831             }
19832         }
19833
19834         return intent;
19835     }
19836
19837     public final int broadcastIntent(IApplicationThread caller,
19838             Intent intent, String resolvedType, IIntentReceiver resultTo,
19839             int resultCode, String resultData, Bundle resultExtras,
19840             String[] requiredPermissions, int appOp, Bundle bOptions,
19841             boolean serialized, boolean sticky, int userId) {
19842         enforceNotIsolatedCaller("broadcastIntent");
19843         synchronized(this) {
19844             intent = verifyBroadcastLocked(intent);
19845
19846             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19847             final int callingPid = Binder.getCallingPid();
19848             final int callingUid = Binder.getCallingUid();
19849             final long origId = Binder.clearCallingIdentity();
19850             int res = broadcastIntentLocked(callerApp,
19851                     callerApp != null ? callerApp.info.packageName : null,
19852                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19853                     requiredPermissions, appOp, bOptions, serialized, sticky,
19854                     callingPid, callingUid, userId);
19855             Binder.restoreCallingIdentity(origId);
19856             return res;
19857         }
19858     }
19859
19860
19861     int broadcastIntentInPackage(String packageName, int uid,
19862             Intent intent, String resolvedType, IIntentReceiver resultTo,
19863             int resultCode, String resultData, Bundle resultExtras,
19864             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19865             int userId) {
19866         synchronized(this) {
19867             intent = verifyBroadcastLocked(intent);
19868
19869             final long origId = Binder.clearCallingIdentity();
19870             String[] requiredPermissions = requiredPermission == null ? null
19871                     : new String[] {requiredPermission};
19872             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19873                     resultTo, resultCode, resultData, resultExtras,
19874                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19875                     sticky, -1, uid, userId);
19876             Binder.restoreCallingIdentity(origId);
19877             return res;
19878         }
19879     }
19880
19881     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19882         // Refuse possible leaked file descriptors
19883         if (intent != null && intent.hasFileDescriptors() == true) {
19884             throw new IllegalArgumentException("File descriptors passed in Intent");
19885         }
19886
19887         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19888                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19889
19890         synchronized(this) {
19891             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19892                     != PackageManager.PERMISSION_GRANTED) {
19893                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19894                         + Binder.getCallingPid()
19895                         + ", uid=" + Binder.getCallingUid()
19896                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19897                 Slog.w(TAG, msg);
19898                 throw new SecurityException(msg);
19899             }
19900             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19901             if (stickies != null) {
19902                 ArrayList<Intent> list = stickies.get(intent.getAction());
19903                 if (list != null) {
19904                     int N = list.size();
19905                     int i;
19906                     for (i=0; i<N; i++) {
19907                         if (intent.filterEquals(list.get(i))) {
19908                             list.remove(i);
19909                             break;
19910                         }
19911                     }
19912                     if (list.size() <= 0) {
19913                         stickies.remove(intent.getAction());
19914                     }
19915                 }
19916                 if (stickies.size() <= 0) {
19917                     mStickyBroadcasts.remove(userId);
19918                 }
19919             }
19920         }
19921     }
19922
19923     void backgroundServicesFinishedLocked(int userId) {
19924         for (BroadcastQueue queue : mBroadcastQueues) {
19925             queue.backgroundServicesFinishedLocked(userId);
19926         }
19927     }
19928
19929     public void finishReceiver(IBinder who, int resultCode, String resultData,
19930             Bundle resultExtras, boolean resultAbort, int flags) {
19931         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19932
19933         // Refuse possible leaked file descriptors
19934         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19935             throw new IllegalArgumentException("File descriptors passed in Bundle");
19936         }
19937
19938         final long origId = Binder.clearCallingIdentity();
19939         try {
19940             boolean doNext = false;
19941             BroadcastRecord r;
19942
19943             synchronized(this) {
19944                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19945                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19946                 r = queue.getMatchingOrderedReceiver(who);
19947                 if (r != null) {
19948                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19949                         resultData, resultExtras, resultAbort, true);
19950                 }
19951             }
19952
19953             if (doNext) {
19954                 r.queue.processNextBroadcast(false);
19955             }
19956             trimApplications();
19957         } finally {
19958             Binder.restoreCallingIdentity(origId);
19959         }
19960     }
19961
19962     // =========================================================
19963     // INSTRUMENTATION
19964     // =========================================================
19965
19966     public boolean startInstrumentation(ComponentName className,
19967             String profileFile, int flags, Bundle arguments,
19968             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19969             int userId, String abiOverride) {
19970         enforceNotIsolatedCaller("startInstrumentation");
19971         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19972                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19973         // Refuse possible leaked file descriptors
19974         if (arguments != null && arguments.hasFileDescriptors()) {
19975             throw new IllegalArgumentException("File descriptors passed in Bundle");
19976         }
19977
19978         synchronized(this) {
19979             InstrumentationInfo ii = null;
19980             ApplicationInfo ai = null;
19981             try {
19982                 ii = mContext.getPackageManager().getInstrumentationInfo(
19983                     className, STOCK_PM_FLAGS);
19984                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19985                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19986             } catch (PackageManager.NameNotFoundException e) {
19987             } catch (RemoteException e) {
19988             }
19989             if (ii == null) {
19990                 reportStartInstrumentationFailureLocked(watcher, className,
19991                         "Unable to find instrumentation info for: " + className);
19992                 return false;
19993             }
19994             if (ai == null) {
19995                 reportStartInstrumentationFailureLocked(watcher, className,
19996                         "Unable to find instrumentation target package: " + ii.targetPackage);
19997                 return false;
19998             }
19999             if (!ai.hasCode()) {
20000                 reportStartInstrumentationFailureLocked(watcher, className,
20001                         "Instrumentation target has no code: " + ii.targetPackage);
20002                 return false;
20003             }
20004
20005             int match = mContext.getPackageManager().checkSignatures(
20006                     ii.targetPackage, ii.packageName);
20007             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20008                 String msg = "Permission Denial: starting instrumentation "
20009                         + className + " from pid="
20010                         + Binder.getCallingPid()
20011                         + ", uid=" + Binder.getCallingPid()
20012                         + " not allowed because package " + ii.packageName
20013                         + " does not have a signature matching the target "
20014                         + ii.targetPackage;
20015                 reportStartInstrumentationFailureLocked(watcher, className, msg);
20016                 throw new SecurityException(msg);
20017             }
20018
20019             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20020             activeInstr.mClass = className;
20021             String defProcess = ai.processName;;
20022             if (ii.targetProcesses == null) {
20023                 activeInstr.mTargetProcesses = new String[]{ai.processName};
20024             } else if (ii.targetProcesses.equals("*")) {
20025                 activeInstr.mTargetProcesses = new String[0];
20026             } else {
20027                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20028                 defProcess = activeInstr.mTargetProcesses[0];
20029             }
20030             activeInstr.mTargetInfo = ai;
20031             activeInstr.mProfileFile = profileFile;
20032             activeInstr.mArguments = arguments;
20033             activeInstr.mWatcher = watcher;
20034             activeInstr.mUiAutomationConnection = uiAutomationConnection;
20035             activeInstr.mResultClass = className;
20036
20037             final long origId = Binder.clearCallingIdentity();
20038             // Instrumentation can kill and relaunch even persistent processes
20039             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20040                     "start instr");
20041             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20042             app.instr = activeInstr;
20043             activeInstr.mFinished = false;
20044             activeInstr.mRunningProcesses.add(app);
20045             if (!mActiveInstrumentation.contains(activeInstr)) {
20046                 mActiveInstrumentation.add(activeInstr);
20047             }
20048             Binder.restoreCallingIdentity(origId);
20049         }
20050
20051         return true;
20052     }
20053
20054     /**
20055      * Report errors that occur while attempting to start Instrumentation.  Always writes the
20056      * error to the logs, but if somebody is watching, send the report there too.  This enables
20057      * the "am" command to report errors with more information.
20058      *
20059      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20060      * @param cn The component name of the instrumentation.
20061      * @param report The error report.
20062      */
20063     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20064             ComponentName cn, String report) {
20065         Slog.w(TAG, report);
20066         if (watcher != null) {
20067             Bundle results = new Bundle();
20068             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20069             results.putString("Error", report);
20070             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20071         }
20072     }
20073
20074     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20075         if (app.instr == null) {
20076             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20077             return;
20078         }
20079
20080         if (!app.instr.mFinished && results != null) {
20081             if (app.instr.mCurResults == null) {
20082                 app.instr.mCurResults = new Bundle(results);
20083             } else {
20084                 app.instr.mCurResults.putAll(results);
20085             }
20086         }
20087     }
20088
20089     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20090         int userId = UserHandle.getCallingUserId();
20091         // Refuse possible leaked file descriptors
20092         if (results != null && results.hasFileDescriptors()) {
20093             throw new IllegalArgumentException("File descriptors passed in Intent");
20094         }
20095
20096         synchronized(this) {
20097             ProcessRecord app = getRecordForAppLocked(target);
20098             if (app == null) {
20099                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20100                 return;
20101             }
20102             final long origId = Binder.clearCallingIdentity();
20103             addInstrumentationResultsLocked(app, results);
20104             Binder.restoreCallingIdentity(origId);
20105         }
20106     }
20107
20108     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20109         if (app.instr == null) {
20110             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20111             return;
20112         }
20113
20114         if (!app.instr.mFinished) {
20115             if (app.instr.mWatcher != null) {
20116                 Bundle finalResults = app.instr.mCurResults;
20117                 if (finalResults != null) {
20118                     if (app.instr.mCurResults != null && results != null) {
20119                         finalResults.putAll(results);
20120                     }
20121                 } else {
20122                     finalResults = results;
20123                 }
20124                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20125                         app.instr.mClass, resultCode, finalResults);
20126             }
20127
20128             // Can't call out of the system process with a lock held, so post a message.
20129             if (app.instr.mUiAutomationConnection != null) {
20130                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20131                         app.instr.mUiAutomationConnection).sendToTarget();
20132             }
20133             app.instr.mFinished = true;
20134         }
20135
20136         app.instr.removeProcess(app);
20137         app.instr = null;
20138
20139         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20140                 "finished inst");
20141     }
20142
20143     public void finishInstrumentation(IApplicationThread target,
20144             int resultCode, Bundle results) {
20145         int userId = UserHandle.getCallingUserId();
20146         // Refuse possible leaked file descriptors
20147         if (results != null && results.hasFileDescriptors()) {
20148             throw new IllegalArgumentException("File descriptors passed in Intent");
20149         }
20150
20151         synchronized(this) {
20152             ProcessRecord app = getRecordForAppLocked(target);
20153             if (app == null) {
20154                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20155                 return;
20156             }
20157             final long origId = Binder.clearCallingIdentity();
20158             finishInstrumentationLocked(app, resultCode, results);
20159             Binder.restoreCallingIdentity(origId);
20160         }
20161     }
20162
20163     // =========================================================
20164     // CONFIGURATION
20165     // =========================================================
20166
20167     public ConfigurationInfo getDeviceConfigurationInfo() {
20168         ConfigurationInfo config = new ConfigurationInfo();
20169         synchronized (this) {
20170             final Configuration globalConfig = getGlobalConfiguration();
20171             config.reqTouchScreen = globalConfig.touchscreen;
20172             config.reqKeyboardType = globalConfig.keyboard;
20173             config.reqNavigation = globalConfig.navigation;
20174             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20175                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20176                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20177             }
20178             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20179                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20180                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20181             }
20182             config.reqGlEsVersion = GL_ES_VERSION;
20183         }
20184         return config;
20185     }
20186
20187     ActivityStack getFocusedStack() {
20188         return mStackSupervisor.getFocusedStack();
20189     }
20190
20191     @Override
20192     public int getFocusedStackId() throws RemoteException {
20193         ActivityStack focusedStack = getFocusedStack();
20194         if (focusedStack != null) {
20195             return focusedStack.getStackId();
20196         }
20197         return -1;
20198     }
20199
20200     public Configuration getConfiguration() {
20201         Configuration ci;
20202         synchronized(this) {
20203             ci = new Configuration(getGlobalConfiguration());
20204             ci.userSetLocale = false;
20205         }
20206         return ci;
20207     }
20208
20209     @Override
20210     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20211         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20212         synchronized (this) {
20213             mSuppressResizeConfigChanges = suppress;
20214         }
20215     }
20216
20217     /**
20218      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20219      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20220      *       activity and clearing the task at the same time.
20221      */
20222     @Override
20223     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20224         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20225         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20226             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20227         }
20228         synchronized (this) {
20229             final long origId = Binder.clearCallingIdentity();
20230             try {
20231                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20232             } finally {
20233                 Binder.restoreCallingIdentity(origId);
20234             }
20235         }
20236     }
20237
20238     @Override
20239     public void updatePersistentConfiguration(Configuration values) {
20240         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20241         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20242         if (values == null) {
20243             throw new NullPointerException("Configuration must not be null");
20244         }
20245
20246         int userId = UserHandle.getCallingUserId();
20247
20248         synchronized(this) {
20249             updatePersistentConfigurationLocked(values, userId);
20250         }
20251     }
20252
20253     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20254         final long origId = Binder.clearCallingIdentity();
20255         try {
20256             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20257         } finally {
20258             Binder.restoreCallingIdentity(origId);
20259         }
20260     }
20261
20262     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20263         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20264                 FONT_SCALE, 1.0f, userId);
20265
20266         synchronized (this) {
20267             if (getGlobalConfiguration().fontScale == scaleFactor) {
20268                 return;
20269             }
20270
20271             final Configuration configuration
20272                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20273             configuration.fontScale = scaleFactor;
20274             updatePersistentConfigurationLocked(configuration, userId);
20275         }
20276     }
20277
20278     private void enforceWriteSettingsPermission(String func) {
20279         int uid = Binder.getCallingUid();
20280         if (uid == ROOT_UID) {
20281             return;
20282         }
20283
20284         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20285                 Settings.getPackageNameForUid(mContext, uid), false)) {
20286             return;
20287         }
20288
20289         String msg = "Permission Denial: " + func + " from pid="
20290                 + Binder.getCallingPid()
20291                 + ", uid=" + uid
20292                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20293         Slog.w(TAG, msg);
20294         throw new SecurityException(msg);
20295     }
20296
20297     @Override
20298     public boolean updateConfiguration(Configuration values) {
20299         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20300
20301         synchronized(this) {
20302             if (values == null && mWindowManager != null) {
20303                 // sentinel: fetch the current configuration from the window manager
20304                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20305             }
20306
20307             if (mWindowManager != null) {
20308                 // Update OOM levels based on display size.
20309                 mProcessList.applyDisplaySize(mWindowManager);
20310             }
20311
20312             final long origId = Binder.clearCallingIdentity();
20313             try {
20314                 if (values != null) {
20315                     Settings.System.clearConfiguration(values);
20316                 }
20317                 updateConfigurationLocked(values, null, false, false /* persistent */,
20318                         UserHandle.USER_NULL, false /* deferResume */,
20319                         mTmpUpdateConfigurationResult);
20320                 return mTmpUpdateConfigurationResult.changes != 0;
20321             } finally {
20322                 Binder.restoreCallingIdentity(origId);
20323             }
20324         }
20325     }
20326
20327     void updateUserConfigurationLocked() {
20328         final Configuration configuration = new Configuration(getGlobalConfiguration());
20329         final int currentUserId = mUserController.getCurrentUserIdLocked();
20330         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20331                 currentUserId, Settings.System.canWrite(mContext));
20332         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20333                 false /* persistent */, currentUserId, false /* deferResume */);
20334     }
20335
20336     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20337             boolean initLocale) {
20338         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20339     }
20340
20341     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20342             boolean initLocale, boolean deferResume) {
20343         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20344         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20345                 UserHandle.USER_NULL, deferResume);
20346     }
20347
20348     // To cache the list of supported system locales
20349     private String[] mSupportedSystemLocales = null;
20350
20351     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20352             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20353         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20354                 deferResume, null /* result */);
20355     }
20356
20357     /**
20358      * Do either or both things: (1) change the current configuration, and (2)
20359      * make sure the given activity is running with the (now) current
20360      * configuration.  Returns true if the activity has been left running, or
20361      * false if <var>starting</var> is being destroyed to match the new
20362      * configuration.
20363      *
20364      * @param userId is only used when persistent parameter is set to true to persist configuration
20365      *               for that particular user
20366      */
20367     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20368             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20369             UpdateConfigurationResult result) {
20370         int changes = 0;
20371         boolean kept = true;
20372
20373         if (mWindowManager != null) {
20374             mWindowManager.deferSurfaceLayout();
20375         }
20376         try {
20377             if (values != null) {
20378                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20379                         deferResume);
20380             }
20381
20382             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20383         } finally {
20384             if (mWindowManager != null) {
20385                 mWindowManager.continueSurfaceLayout();
20386             }
20387         }
20388
20389         if (result != null) {
20390             result.changes = changes;
20391             result.activityRelaunched = !kept;
20392         }
20393         return kept;
20394     }
20395
20396     /** Update default (global) configuration and notify listeners about changes. */
20397     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20398             boolean persistent, int userId, boolean deferResume) {
20399         mTempConfig.setTo(getGlobalConfiguration());
20400         final int changes = mTempConfig.updateFrom(values);
20401         if (changes == 0) {
20402             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20403             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20404             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20405             // (even if there are no actual changes) to unfreeze the window.
20406             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20407             return 0;
20408         }
20409
20410         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20411                 "Updating global configuration to: " + values);
20412
20413         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20414
20415         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20416             final LocaleList locales = values.getLocales();
20417             int bestLocaleIndex = 0;
20418             if (locales.size() > 1) {
20419                 if (mSupportedSystemLocales == null) {
20420                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20421                 }
20422                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20423             }
20424             SystemProperties.set("persist.sys.locale",
20425                     locales.get(bestLocaleIndex).toLanguageTag());
20426             LocaleList.setDefault(locales, bestLocaleIndex);
20427             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20428                     locales.get(bestLocaleIndex)));
20429         }
20430
20431         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20432         mTempConfig.seq = mConfigurationSeq;
20433
20434         // Update stored global config and notify everyone about the change.
20435         mStackSupervisor.onConfigurationChanged(mTempConfig);
20436
20437         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20438         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20439         mUsageStatsService.reportConfigurationChange(mTempConfig,
20440                 mUserController.getCurrentUserIdLocked());
20441
20442         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20443         mShowDialogs = shouldShowDialogs(mTempConfig);
20444
20445         AttributeCache ac = AttributeCache.instance();
20446         if (ac != null) {
20447             ac.updateConfiguration(mTempConfig);
20448         }
20449
20450         // Make sure all resources in our process are updated right now, so that anyone who is going
20451         // to retrieve resource values after we return will be sure to get the new ones. This is
20452         // especially important during boot, where the first config change needs to guarantee all
20453         // resources have that config before following boot code is executed.
20454         mSystemThread.applyConfigurationToResources(mTempConfig);
20455
20456         // We need another copy of global config because we're scheduling some calls instead of
20457         // running them in place. We need to be sure that object we send will be handled unchanged.
20458         final Configuration configCopy = new Configuration(mTempConfig);
20459         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20460             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20461             msg.obj = configCopy;
20462             msg.arg1 = userId;
20463             mHandler.sendMessage(msg);
20464         }
20465
20466         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20467             ProcessRecord app = mLruProcesses.get(i);
20468             try {
20469                 if (app.thread != null) {
20470                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20471                             + app.processName + " new config " + configCopy);
20472                     app.thread.scheduleConfigurationChanged(configCopy);
20473                 }
20474             } catch (Exception e) {
20475             }
20476         }
20477
20478         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20479         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20480                 | Intent.FLAG_RECEIVER_FOREGROUND
20481                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20482         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20483                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20484                 UserHandle.USER_ALL);
20485         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20486             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20487             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20488                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20489                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20490             if (initLocale || !mProcessesReady) {
20491                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20492             }
20493             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20494                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20495                     UserHandle.USER_ALL);
20496         }
20497
20498         // Override configuration of the default display duplicates global config, so we need to
20499         // update it also. This will also notify WindowManager about changes.
20500         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20501                 DEFAULT_DISPLAY);
20502
20503         return changes;
20504     }
20505
20506     @Override
20507     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20508         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20509
20510         synchronized (this) {
20511             // Check if display is initialized in AM.
20512             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20513                 // Call might come when display is not yet added or has already been removed.
20514                 if (DEBUG_CONFIGURATION) {
20515                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20516                             + displayId);
20517                 }
20518                 return false;
20519             }
20520
20521             if (values == null && mWindowManager != null) {
20522                 // sentinel: fetch the current configuration from the window manager
20523                 values = mWindowManager.computeNewConfiguration(displayId);
20524             }
20525
20526             if (mWindowManager != null) {
20527                 // Update OOM levels based on display size.
20528                 mProcessList.applyDisplaySize(mWindowManager);
20529             }
20530
20531             final long origId = Binder.clearCallingIdentity();
20532             try {
20533                 if (values != null) {
20534                     Settings.System.clearConfiguration(values);
20535                 }
20536                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20537                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20538                 return mTmpUpdateConfigurationResult.changes != 0;
20539             } finally {
20540                 Binder.restoreCallingIdentity(origId);
20541             }
20542         }
20543     }
20544
20545     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20546             boolean deferResume, int displayId) {
20547         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20548                 displayId, null /* result */);
20549     }
20550
20551     /**
20552      * Updates override configuration specific for the selected display. If no config is provided,
20553      * new one will be computed in WM based on current display info.
20554      */
20555     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20556             ActivityRecord starting, boolean deferResume, int displayId,
20557             UpdateConfigurationResult result) {
20558         int changes = 0;
20559         boolean kept = true;
20560
20561         if (mWindowManager != null) {
20562             mWindowManager.deferSurfaceLayout();
20563         }
20564         try {
20565             if (values != null) {
20566                 if (displayId == DEFAULT_DISPLAY) {
20567                     // Override configuration of the default display duplicates global config, so
20568                     // we're calling global config update instead for default display. It will also
20569                     // apply the correct override config.
20570                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20571                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20572                 } else {
20573                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20574                 }
20575             }
20576
20577             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20578         } finally {
20579             if (mWindowManager != null) {
20580                 mWindowManager.continueSurfaceLayout();
20581             }
20582         }
20583
20584         if (result != null) {
20585             result.changes = changes;
20586             result.activityRelaunched = !kept;
20587         }
20588         return kept;
20589     }
20590
20591     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20592             int displayId) {
20593         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20594         final int changes = mTempConfig.updateFrom(values);
20595         if (changes != 0) {
20596             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20597                     + mTempConfig + " for displayId=" + displayId);
20598             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20599
20600             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20601             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20602                 // Reset the unsupported display size dialog.
20603                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20604
20605                 killAllBackgroundProcessesExcept(N,
20606                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20607             }
20608         }
20609
20610         // Update the configuration with WM first and check if any of the stacks need to be resized
20611         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20612         // necessary. This way we don't need to relaunch again afterwards in
20613         // ensureActivityConfigurationLocked().
20614         if (mWindowManager != null) {
20615             final int[] resizedStacks =
20616                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20617             if (resizedStacks != null) {
20618                 for (int stackId : resizedStacks) {
20619                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20620                 }
20621             }
20622         }
20623
20624         return changes;
20625     }
20626
20627     /** Applies latest configuration and/or visibility updates if needed. */
20628     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20629         boolean kept = true;
20630         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20631         // mainStack is null during startup.
20632         if (mainStack != null) {
20633             if (changes != 0 && starting == null) {
20634                 // If the configuration changed, and the caller is not already
20635                 // in the process of starting an activity, then find the top
20636                 // activity to check if its configuration needs to change.
20637                 starting = mainStack.topRunningActivityLocked();
20638             }
20639
20640             if (starting != null) {
20641                 kept = starting.ensureActivityConfigurationLocked(changes,
20642                         false /* preserveWindow */);
20643                 // And we need to make sure at this point that all other activities
20644                 // are made visible with the correct configuration.
20645                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20646                         !PRESERVE_WINDOWS);
20647             }
20648         }
20649
20650         return kept;
20651     }
20652
20653     /** Helper method that requests bounds from WM and applies them to stack. */
20654     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20655         final Rect newStackBounds = new Rect();
20656         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20657         mStackSupervisor.resizeStackLocked(
20658                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20659                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20660                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20661     }
20662
20663     /**
20664      * Decide based on the configuration whether we should show the ANR,
20665      * crash, etc dialogs.  The idea is that if there is no affordance to
20666      * press the on-screen buttons, or the user experience would be more
20667      * greatly impacted than the crash itself, we shouldn't show the dialog.
20668      *
20669      * A thought: SystemUI might also want to get told about this, the Power
20670      * dialog / global actions also might want different behaviors.
20671      */
20672     private static boolean shouldShowDialogs(Configuration config) {
20673         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20674                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20675                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20676         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20677         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20678                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20679                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20680                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20681         return inputMethodExists && uiModeSupportsDialogs;
20682     }
20683
20684     @Override
20685     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20686         synchronized (this) {
20687             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20688             if (srec != null) {
20689                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20690             }
20691         }
20692         return false;
20693     }
20694
20695     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20696             Intent resultData) {
20697
20698         synchronized (this) {
20699             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20700             if (r != null) {
20701                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20702             }
20703             return false;
20704         }
20705     }
20706
20707     public int getLaunchedFromUid(IBinder activityToken) {
20708         ActivityRecord srec;
20709         synchronized (this) {
20710             srec = ActivityRecord.forTokenLocked(activityToken);
20711         }
20712         if (srec == null) {
20713             return -1;
20714         }
20715         return srec.launchedFromUid;
20716     }
20717
20718     public String getLaunchedFromPackage(IBinder activityToken) {
20719         ActivityRecord srec;
20720         synchronized (this) {
20721             srec = ActivityRecord.forTokenLocked(activityToken);
20722         }
20723         if (srec == null) {
20724             return null;
20725         }
20726         return srec.launchedFromPackage;
20727     }
20728
20729     // =========================================================
20730     // LIFETIME MANAGEMENT
20731     // =========================================================
20732
20733     // Returns whether the app is receiving broadcast.
20734     // If receiving, fetch all broadcast queues which the app is
20735     // the current [or imminent] receiver on.
20736     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20737             ArraySet<BroadcastQueue> receivingQueues) {
20738         if (!app.curReceivers.isEmpty()) {
20739             for (BroadcastRecord r : app.curReceivers) {
20740                 receivingQueues.add(r.queue);
20741             }
20742             return true;
20743         }
20744
20745         // It's not the current receiver, but it might be starting up to become one
20746         for (BroadcastQueue queue : mBroadcastQueues) {
20747             final BroadcastRecord r = queue.mPendingBroadcast;
20748             if (r != null && r.curApp == app) {
20749                 // found it; report which queue it's in
20750                 receivingQueues.add(queue);
20751             }
20752         }
20753
20754         return !receivingQueues.isEmpty();
20755     }
20756
20757     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20758             int targetUid, ComponentName targetComponent, String targetProcess) {
20759         if (!mTrackingAssociations) {
20760             return null;
20761         }
20762         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20763                 = mAssociations.get(targetUid);
20764         if (components == null) {
20765             components = new ArrayMap<>();
20766             mAssociations.put(targetUid, components);
20767         }
20768         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20769         if (sourceUids == null) {
20770             sourceUids = new SparseArray<>();
20771             components.put(targetComponent, sourceUids);
20772         }
20773         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20774         if (sourceProcesses == null) {
20775             sourceProcesses = new ArrayMap<>();
20776             sourceUids.put(sourceUid, sourceProcesses);
20777         }
20778         Association ass = sourceProcesses.get(sourceProcess);
20779         if (ass == null) {
20780             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20781                     targetProcess);
20782             sourceProcesses.put(sourceProcess, ass);
20783         }
20784         ass.mCount++;
20785         ass.mNesting++;
20786         if (ass.mNesting == 1) {
20787             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20788             ass.mLastState = sourceState;
20789         }
20790         return ass;
20791     }
20792
20793     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20794             ComponentName targetComponent) {
20795         if (!mTrackingAssociations) {
20796             return;
20797         }
20798         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20799                 = mAssociations.get(targetUid);
20800         if (components == null) {
20801             return;
20802         }
20803         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20804         if (sourceUids == null) {
20805             return;
20806         }
20807         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20808         if (sourceProcesses == null) {
20809             return;
20810         }
20811         Association ass = sourceProcesses.get(sourceProcess);
20812         if (ass == null || ass.mNesting <= 0) {
20813             return;
20814         }
20815         ass.mNesting--;
20816         if (ass.mNesting == 0) {
20817             long uptime = SystemClock.uptimeMillis();
20818             ass.mTime += uptime - ass.mStartTime;
20819             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20820                     += uptime - ass.mLastStateUptime;
20821             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20822         }
20823     }
20824
20825     private void noteUidProcessState(final int uid, final int state) {
20826         mBatteryStatsService.noteUidProcessState(uid, state);
20827         if (mTrackingAssociations) {
20828             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20829                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20830                         = mAssociations.valueAt(i1);
20831                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20832                     SparseArray<ArrayMap<String, Association>> sourceUids
20833                             = targetComponents.valueAt(i2);
20834                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20835                     if (sourceProcesses != null) {
20836                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20837                             Association ass = sourceProcesses.valueAt(i4);
20838                             if (ass.mNesting >= 1) {
20839                                 // currently associated
20840                                 long uptime = SystemClock.uptimeMillis();
20841                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20842                                         += uptime - ass.mLastStateUptime;
20843                                 ass.mLastState = state;
20844                                 ass.mLastStateUptime = uptime;
20845                             }
20846                         }
20847                     }
20848                 }
20849             }
20850         }
20851     }
20852
20853     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20854             boolean doingAll, long now) {
20855         if (mAdjSeq == app.adjSeq) {
20856             // This adjustment has already been computed.
20857             return app.curRawAdj;
20858         }
20859
20860         if (app.thread == null) {
20861             app.adjSeq = mAdjSeq;
20862             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20863             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20864             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20865         }
20866
20867         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20868         app.adjSource = null;
20869         app.adjTarget = null;
20870         app.empty = false;
20871         app.cached = false;
20872
20873         final int activitiesSize = app.activities.size();
20874
20875         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20876             // The max adjustment doesn't allow this app to be anything
20877             // below foreground, so it is not worth doing work for it.
20878             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20879             app.adjType = "fixed";
20880             app.adjSeq = mAdjSeq;
20881             app.curRawAdj = app.maxAdj;
20882             app.foregroundActivities = false;
20883             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20884             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20885             // System processes can do UI, and when they do we want to have
20886             // them trim their memory after the user leaves the UI.  To
20887             // facilitate this, here we need to determine whether or not it
20888             // is currently showing UI.
20889             app.systemNoUi = true;
20890             if (app == TOP_APP) {
20891                 app.systemNoUi = false;
20892                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20893                 app.adjType = "pers-top-activity";
20894             } else if (app.hasTopUi) {
20895                 app.systemNoUi = false;
20896                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20897                 app.adjType = "pers-top-ui";
20898             } else if (activitiesSize > 0) {
20899                 for (int j = 0; j < activitiesSize; j++) {
20900                     final ActivityRecord r = app.activities.get(j);
20901                     if (r.visible) {
20902                         app.systemNoUi = false;
20903                     }
20904                 }
20905             }
20906             if (!app.systemNoUi) {
20907                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20908             }
20909             return (app.curAdj=app.maxAdj);
20910         }
20911
20912         app.systemNoUi = false;
20913
20914         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20915
20916         // Determine the importance of the process, starting with most
20917         // important to least, and assign an appropriate OOM adjustment.
20918         int adj;
20919         int schedGroup;
20920         int procState;
20921         boolean foregroundActivities = false;
20922         mTmpBroadcastQueue.clear();
20923         if (app == TOP_APP) {
20924             // The last app on the list is the foreground app.
20925             adj = ProcessList.FOREGROUND_APP_ADJ;
20926             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20927             app.adjType = "top-activity";
20928             foregroundActivities = true;
20929             procState = PROCESS_STATE_CUR_TOP;
20930             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20931         } else if (app.instr != null) {
20932             // Don't want to kill running instrumentation.
20933             adj = ProcessList.FOREGROUND_APP_ADJ;
20934             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20935             app.adjType = "instrumentation";
20936             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20937             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20938         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20939             // An app that is currently receiving a broadcast also
20940             // counts as being in the foreground for OOM killer purposes.
20941             // It's placed in a sched group based on the nature of the
20942             // broadcast as reflected by which queue it's active in.
20943             adj = ProcessList.FOREGROUND_APP_ADJ;
20944             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20945                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20946             app.adjType = "broadcast";
20947             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20948             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20949         } else if (app.executingServices.size() > 0) {
20950             // An app that is currently executing a service callback also
20951             // counts as being in the foreground.
20952             adj = ProcessList.FOREGROUND_APP_ADJ;
20953             schedGroup = app.execServicesFg ?
20954                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20955             app.adjType = "exec-service";
20956             procState = ActivityManager.PROCESS_STATE_SERVICE;
20957             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20958             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20959         } else {
20960             // As far as we know the process is empty.  We may change our mind later.
20961             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20962             // At this point we don't actually know the adjustment.  Use the cached adj
20963             // value that the caller wants us to.
20964             adj = cachedAdj;
20965             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20966             app.cached = true;
20967             app.empty = true;
20968             app.adjType = "cch-empty";
20969             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20970         }
20971
20972         // Examine all activities if not already foreground.
20973         if (!foregroundActivities && activitiesSize > 0) {
20974             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20975             for (int j = 0; j < activitiesSize; j++) {
20976                 final ActivityRecord r = app.activities.get(j);
20977                 if (r.app != app) {
20978                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20979                             + " instead of expected " + app);
20980                     if (r.app == null || (r.app.uid == app.uid)) {
20981                         // Only fix things up when they look sane
20982                         r.app = app;
20983                     } else {
20984                         continue;
20985                     }
20986                 }
20987                 if (r.visible) {
20988                     // App has a visible activity; only upgrade adjustment.
20989                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20990                         adj = ProcessList.VISIBLE_APP_ADJ;
20991                         app.adjType = "vis-activity";
20992                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20993                     }
20994                     if (procState > PROCESS_STATE_CUR_TOP) {
20995                         procState = PROCESS_STATE_CUR_TOP;
20996                         app.adjType = "vis-activity";
20997                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20998                     }
20999                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21000                     app.cached = false;
21001                     app.empty = false;
21002                     foregroundActivities = true;
21003                     final TaskRecord task = r.getTask();
21004                     if (task != null && minLayer > 0) {
21005                         final int layer = task.mLayerRank;
21006                         if (layer >= 0 && minLayer > layer) {
21007                             minLayer = layer;
21008                         }
21009                     }
21010                     break;
21011                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21012                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21013                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21014                         app.adjType = "pause-activity";
21015                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21016                     }
21017                     if (procState > PROCESS_STATE_CUR_TOP) {
21018                         procState = PROCESS_STATE_CUR_TOP;
21019                         app.adjType = "pause-activity";
21020                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21021                     }
21022                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21023                     app.cached = false;
21024                     app.empty = false;
21025                     foregroundActivities = true;
21026                 } else if (r.state == ActivityState.STOPPING) {
21027                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21028                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21029                         app.adjType = "stop-activity";
21030                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21031                     }
21032                     // For the process state, we will at this point consider the
21033                     // process to be cached.  It will be cached either as an activity
21034                     // or empty depending on whether the activity is finishing.  We do
21035                     // this so that we can treat the process as cached for purposes of
21036                     // memory trimming (determing current memory level, trim command to
21037                     // send to process) since there can be an arbitrary number of stopping
21038                     // processes and they should soon all go into the cached state.
21039                     if (!r.finishing) {
21040                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21041                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21042                             app.adjType = "stop-activity";
21043                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21044                         }
21045                     }
21046                     app.cached = false;
21047                     app.empty = false;
21048                     foregroundActivities = true;
21049                 } else {
21050                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21051                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21052                         app.adjType = "cch-act";
21053                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21054                     }
21055                 }
21056             }
21057             if (adj == ProcessList.VISIBLE_APP_ADJ) {
21058                 adj += minLayer;
21059             }
21060         }
21061
21062         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21063                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21064             if (app.foregroundServices) {
21065                 // The user is aware of this app, so make it visible.
21066                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21067                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21068                 app.cached = false;
21069                 app.adjType = "fg-service";
21070                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21071                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21072             } else if (app.hasOverlayUi) {
21073                 // The process is display an overlay UI.
21074                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21075                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21076                 app.cached = false;
21077                 app.adjType = "has-overlay-ui";
21078                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21079                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21080             }
21081         }
21082
21083         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21084                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21085             if (app.forcingToImportant != null) {
21086                 // This is currently used for toasts...  they are not interactive, and
21087                 // we don't want them to cause the app to become fully foreground (and
21088                 // thus out of background check), so we yes the best background level we can.
21089                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21090                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21091                 app.cached = false;
21092                 app.adjType = "force-imp";
21093                 app.adjSource = app.forcingToImportant;
21094                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21095                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21096             }
21097         }
21098
21099         if (app == mHeavyWeightProcess) {
21100             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21101                 // We don't want to kill the current heavy-weight process.
21102                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21103                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21104                 app.cached = false;
21105                 app.adjType = "heavy";
21106                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21107             }
21108             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21109                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21110                 app.adjType = "heavy";
21111                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21112             }
21113         }
21114
21115         if (app == mHomeProcess) {
21116             if (adj > ProcessList.HOME_APP_ADJ) {
21117                 // This process is hosting what we currently consider to be the
21118                 // home app, so we don't want to let it go into the background.
21119                 adj = ProcessList.HOME_APP_ADJ;
21120                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21121                 app.cached = false;
21122                 app.adjType = "home";
21123                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21124             }
21125             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21126                 procState = ActivityManager.PROCESS_STATE_HOME;
21127                 app.adjType = "home";
21128                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21129             }
21130         }
21131
21132         if (app == mPreviousProcess && app.activities.size() > 0) {
21133             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21134                 // This was the previous process that showed UI to the user.
21135                 // We want to try to keep it around more aggressively, to give
21136                 // a good experience around switching between two apps.
21137                 adj = ProcessList.PREVIOUS_APP_ADJ;
21138                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21139                 app.cached = false;
21140                 app.adjType = "previous";
21141                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21142             }
21143             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21144                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21145                 app.adjType = "previous";
21146                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21147             }
21148         }
21149
21150         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21151                 + " reason=" + app.adjType);
21152
21153         // By default, we use the computed adjustment.  It may be changed if
21154         // there are applications dependent on our services or providers, but
21155         // this gives us a baseline and makes sure we don't get into an
21156         // infinite recursion.
21157         app.adjSeq = mAdjSeq;
21158         app.curRawAdj = adj;
21159         app.hasStartedServices = false;
21160
21161         if (mBackupTarget != null && app == mBackupTarget.app) {
21162             // If possible we want to avoid killing apps while they're being backed up
21163             if (adj > ProcessList.BACKUP_APP_ADJ) {
21164                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21165                 adj = ProcessList.BACKUP_APP_ADJ;
21166                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21167                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21168                 }
21169                 app.adjType = "backup";
21170                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21171                 app.cached = false;
21172             }
21173             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21174                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21175                 app.adjType = "backup";
21176                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21177             }
21178         }
21179
21180         boolean mayBeTop = false;
21181         String mayBeTopType = null;
21182         Object mayBeTopSource = null;
21183         Object mayBeTopTarget = null;
21184
21185         for (int is = app.services.size()-1;
21186                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21187                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21188                         || procState > ActivityManager.PROCESS_STATE_TOP);
21189                 is--) {
21190             ServiceRecord s = app.services.valueAt(is);
21191             if (s.startRequested) {
21192                 app.hasStartedServices = true;
21193                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21194                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21195                     app.adjType = "started-services";
21196                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21197                 }
21198                 if (app.hasShownUi && app != mHomeProcess) {
21199                     // If this process has shown some UI, let it immediately
21200                     // go to the LRU list because it may be pretty heavy with
21201                     // UI stuff.  We'll tag it with a label just to help
21202                     // debug and understand what is going on.
21203                     if (adj > ProcessList.SERVICE_ADJ) {
21204                         app.adjType = "cch-started-ui-services";
21205                     }
21206                 } else {
21207                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21208                         // This service has seen some activity within
21209                         // recent memory, so we will keep its process ahead
21210                         // of the background processes.
21211                         if (adj > ProcessList.SERVICE_ADJ) {
21212                             adj = ProcessList.SERVICE_ADJ;
21213                             app.adjType = "started-services";
21214                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21215                             app.cached = false;
21216                         }
21217                     }
21218                     // If we have let the service slide into the background
21219                     // state, still have some text describing what it is doing
21220                     // even though the service no longer has an impact.
21221                     if (adj > ProcessList.SERVICE_ADJ) {
21222                         app.adjType = "cch-started-services";
21223                     }
21224                 }
21225             }
21226
21227             for (int conni = s.connections.size()-1;
21228                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21229                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21230                             || procState > ActivityManager.PROCESS_STATE_TOP);
21231                     conni--) {
21232                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21233                 for (int i = 0;
21234                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21235                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21236                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21237                         i++) {
21238                     // XXX should compute this based on the max of
21239                     // all connected clients.
21240                     ConnectionRecord cr = clist.get(i);
21241                     if (cr.binding.client == app) {
21242                         // Binding to ourself is not interesting.
21243                         continue;
21244                     }
21245
21246                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21247                         ProcessRecord client = cr.binding.client;
21248                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21249                                 TOP_APP, doingAll, now);
21250                         int clientProcState = client.curProcState;
21251                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21252                             // If the other app is cached for any reason, for purposes here
21253                             // we are going to consider it empty.  The specific cached state
21254                             // doesn't propagate except under certain conditions.
21255                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21256                         }
21257                         String adjType = null;
21258                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21259                             // Not doing bind OOM management, so treat
21260                             // this guy more like a started service.
21261                             if (app.hasShownUi && app != mHomeProcess) {
21262                                 // If this process has shown some UI, let it immediately
21263                                 // go to the LRU list because it may be pretty heavy with
21264                                 // UI stuff.  We'll tag it with a label just to help
21265                                 // debug and understand what is going on.
21266                                 if (adj > clientAdj) {
21267                                     adjType = "cch-bound-ui-services";
21268                                 }
21269                                 app.cached = false;
21270                                 clientAdj = adj;
21271                                 clientProcState = procState;
21272                             } else {
21273                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21274                                     // This service has not seen activity within
21275                                     // recent memory, so allow it to drop to the
21276                                     // LRU list if there is no other reason to keep
21277                                     // it around.  We'll also tag it with a label just
21278                                     // to help debug and undertand what is going on.
21279                                     if (adj > clientAdj) {
21280                                         adjType = "cch-bound-services";
21281                                     }
21282                                     clientAdj = adj;
21283                                 }
21284                             }
21285                         }
21286                         if (adj > clientAdj) {
21287                             // If this process has recently shown UI, and
21288                             // the process that is binding to it is less
21289                             // important than being visible, then we don't
21290                             // care about the binding as much as we care
21291                             // about letting this process get into the LRU
21292                             // list to be killed and restarted if needed for
21293                             // memory.
21294                             if (app.hasShownUi && app != mHomeProcess
21295                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21296                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21297                                     adjType = "cch-bound-ui-services";
21298                                 }
21299                             } else {
21300                                 int newAdj;
21301                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21302                                         |Context.BIND_IMPORTANT)) != 0) {
21303                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21304                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21305                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21306                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21307                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21308                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21309                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21310                                     newAdj = clientAdj;
21311                                 } else {
21312                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21313                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21314                                     } else {
21315                                         newAdj = adj;
21316                                     }
21317                                 }
21318                                 if (!client.cached) {
21319                                     app.cached = false;
21320                                 }
21321                                 if (adj >  newAdj) {
21322                                     adj = newAdj;
21323                                     adjType = "service";
21324                                 }
21325                             }
21326                         }
21327                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21328                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21329                             // This will treat important bound services identically to
21330                             // the top app, which may behave differently than generic
21331                             // foreground work.
21332                             if (client.curSchedGroup > schedGroup) {
21333                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21334                                     schedGroup = client.curSchedGroup;
21335                                 } else {
21336                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21337                                 }
21338                             }
21339                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21340                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21341                                     // Special handling of clients who are in the top state.
21342                                     // We *may* want to consider this process to be in the
21343                                     // top state as well, but only if there is not another
21344                                     // reason for it to be running.  Being on the top is a
21345                                     // special state, meaning you are specifically running
21346                                     // for the current top app.  If the process is already
21347                                     // running in the background for some other reason, it
21348                                     // is more important to continue considering it to be
21349                                     // in the background state.
21350                                     mayBeTop = true;
21351                                     mayBeTopType = "service";
21352                                     mayBeTopSource = cr.binding.client;
21353                                     mayBeTopTarget = s.name;
21354                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21355                                 } else {
21356                                     // Special handling for above-top states (persistent
21357                                     // processes).  These should not bring the current process
21358                                     // into the top state, since they are not on top.  Instead
21359                                     // give them the best state after that.
21360                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21361                                         clientProcState =
21362                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21363                                     } else if (mWakefulness
21364                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21365                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21366                                                     != 0) {
21367                                         clientProcState =
21368                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21369                                     } else {
21370                                         clientProcState =
21371                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21372                                     }
21373                                 }
21374                             }
21375                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21376                             if (clientProcState <
21377                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21378                                 clientProcState =
21379                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21380                             }
21381                         } else {
21382                             if (clientProcState <
21383                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21384                                 clientProcState =
21385                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21386                             }
21387                         }
21388                         if (procState > clientProcState) {
21389                             procState = clientProcState;
21390                             if (adjType == null) {
21391                                 adjType = "service";
21392                             }
21393                         }
21394                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21395                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21396                             app.pendingUiClean = true;
21397                         }
21398                         if (adjType != null) {
21399                             app.adjType = adjType;
21400                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21401                                     .REASON_SERVICE_IN_USE;
21402                             app.adjSource = cr.binding.client;
21403                             app.adjSourceProcState = clientProcState;
21404                             app.adjTarget = s.name;
21405                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21406                                     + ": " + app + ", due to " + cr.binding.client
21407                                     + " adj=" + adj + " procState=" + procState);
21408                         }
21409                     }
21410                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21411                         app.treatLikeActivity = true;
21412                     }
21413                     final ActivityRecord a = cr.activity;
21414                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21415                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21416                             (a.visible || a.state == ActivityState.RESUMED ||
21417                              a.state == ActivityState.PAUSING)) {
21418                             adj = ProcessList.FOREGROUND_APP_ADJ;
21419                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21420                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21421                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21422                                 } else {
21423                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21424                                 }
21425                             }
21426                             app.cached = false;
21427                             app.adjType = "service";
21428                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21429                                     .REASON_SERVICE_IN_USE;
21430                             app.adjSource = a;
21431                             app.adjSourceProcState = procState;
21432                             app.adjTarget = s.name;
21433                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21434                                     + app);
21435                         }
21436                     }
21437                 }
21438             }
21439         }
21440
21441         for (int provi = app.pubProviders.size()-1;
21442                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21443                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21444                         || procState > ActivityManager.PROCESS_STATE_TOP);
21445                 provi--) {
21446             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21447             for (int i = cpr.connections.size()-1;
21448                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21449                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21450                             || procState > ActivityManager.PROCESS_STATE_TOP);
21451                     i--) {
21452                 ContentProviderConnection conn = cpr.connections.get(i);
21453                 ProcessRecord client = conn.client;
21454                 if (client == app) {
21455                     // Being our own client is not interesting.
21456                     continue;
21457                 }
21458                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21459                 int clientProcState = client.curProcState;
21460                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21461                     // If the other app is cached for any reason, for purposes here
21462                     // we are going to consider it empty.
21463                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21464                 }
21465                 String adjType = null;
21466                 if (adj > clientAdj) {
21467                     if (app.hasShownUi && app != mHomeProcess
21468                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21469                         adjType = "cch-ui-provider";
21470                     } else {
21471                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21472                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21473                         adjType = "provider";
21474                     }
21475                     app.cached &= client.cached;
21476                 }
21477                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21478                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21479                         // Special handling of clients who are in the top state.
21480                         // We *may* want to consider this process to be in the
21481                         // top state as well, but only if there is not another
21482                         // reason for it to be running.  Being on the top is a
21483                         // special state, meaning you are specifically running
21484                         // for the current top app.  If the process is already
21485                         // running in the background for some other reason, it
21486                         // is more important to continue considering it to be
21487                         // in the background state.
21488                         mayBeTop = true;
21489                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21490                         mayBeTopType = adjType = "provider-top";
21491                         mayBeTopSource = client;
21492                         mayBeTopTarget = cpr.name;
21493                     } else {
21494                         // Special handling for above-top states (persistent
21495                         // processes).  These should not bring the current process
21496                         // into the top state, since they are not on top.  Instead
21497                         // give them the best state after that.
21498                         clientProcState =
21499                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21500                         if (adjType == null) {
21501                             adjType = "provider";
21502                         }
21503                     }
21504                 }
21505                 if (procState > clientProcState) {
21506                     procState = clientProcState;
21507                 }
21508                 if (client.curSchedGroup > schedGroup) {
21509                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21510                 }
21511                 if (adjType != null) {
21512                     app.adjType = adjType;
21513                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21514                             .REASON_PROVIDER_IN_USE;
21515                     app.adjSource = client;
21516                     app.adjSourceProcState = clientProcState;
21517                     app.adjTarget = cpr.name;
21518                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21519                             + ": " + app + ", due to " + client
21520                             + " adj=" + adj + " procState=" + procState);
21521                 }
21522             }
21523             // If the provider has external (non-framework) process
21524             // dependencies, ensure that its adjustment is at least
21525             // FOREGROUND_APP_ADJ.
21526             if (cpr.hasExternalProcessHandles()) {
21527                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21528                     adj = ProcessList.FOREGROUND_APP_ADJ;
21529                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21530                     app.cached = false;
21531                     app.adjType = "ext-provider";
21532                     app.adjTarget = cpr.name;
21533                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21534                 }
21535                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21536                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21537                 }
21538             }
21539         }
21540
21541         if (app.lastProviderTime > 0 &&
21542                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21543             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21544                 adj = ProcessList.PREVIOUS_APP_ADJ;
21545                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21546                 app.cached = false;
21547                 app.adjType = "recent-provider";
21548                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21549             }
21550             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21551                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21552                 app.adjType = "recent-provider";
21553                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21554             }
21555         }
21556
21557         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21558             // A client of one of our services or providers is in the top state.  We
21559             // *may* want to be in the top state, but not if we are already running in
21560             // the background for some other reason.  For the decision here, we are going
21561             // to pick out a few specific states that we want to remain in when a client
21562             // is top (states that tend to be longer-term) and otherwise allow it to go
21563             // to the top state.
21564             switch (procState) {
21565                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21566                     // Something else is keeping it at this level, just leave it.
21567                     break;
21568                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21569                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21570                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21571                 case ActivityManager.PROCESS_STATE_SERVICE:
21572                     // These all are longer-term states, so pull them up to the top
21573                     // of the background states, but not all the way to the top state.
21574                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21575                     app.adjType = mayBeTopType;
21576                     app.adjSource = mayBeTopSource;
21577                     app.adjTarget = mayBeTopTarget;
21578                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21579                             + ": " + app + ", due to " + mayBeTopSource
21580                             + " adj=" + adj + " procState=" + procState);
21581                     break;
21582                 default:
21583                     // Otherwise, top is a better choice, so take it.
21584                     procState = ActivityManager.PROCESS_STATE_TOP;
21585                     app.adjType = mayBeTopType;
21586                     app.adjSource = mayBeTopSource;
21587                     app.adjTarget = mayBeTopTarget;
21588                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21589                             + ": " + app + ", due to " + mayBeTopSource
21590                             + " adj=" + adj + " procState=" + procState);
21591                     break;
21592             }
21593         }
21594
21595         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21596             if (app.hasClientActivities) {
21597                 // This is a cached process, but with client activities.  Mark it so.
21598                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21599                 app.adjType = "cch-client-act";
21600             } else if (app.treatLikeActivity) {
21601                 // This is a cached process, but somebody wants us to treat it like it has
21602                 // an activity, okay!
21603                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21604                 app.adjType = "cch-as-act";
21605             }
21606         }
21607
21608         if (adj == ProcessList.SERVICE_ADJ) {
21609             if (doingAll) {
21610                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21611                 mNewNumServiceProcs++;
21612                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21613                 if (!app.serviceb) {
21614                     // This service isn't far enough down on the LRU list to
21615                     // normally be a B service, but if we are low on RAM and it
21616                     // is large we want to force it down since we would prefer to
21617                     // keep launcher over it.
21618                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21619                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21620                         app.serviceHighRam = true;
21621                         app.serviceb = true;
21622                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21623                     } else {
21624                         mNewNumAServiceProcs++;
21625                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21626                     }
21627                 } else {
21628                     app.serviceHighRam = false;
21629                 }
21630             }
21631             if (app.serviceb) {
21632                 adj = ProcessList.SERVICE_B_ADJ;
21633             }
21634         }
21635
21636         app.curRawAdj = adj;
21637
21638         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21639         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21640         if (adj > app.maxAdj) {
21641             adj = app.maxAdj;
21642             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21643                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21644             }
21645         }
21646
21647         // Do final modification to adj.  Everything we do between here and applying
21648         // the final setAdj must be done in this function, because we will also use
21649         // it when computing the final cached adj later.  Note that we don't need to
21650         // worry about this for max adj above, since max adj will always be used to
21651         // keep it out of the cached vaues.
21652         app.curAdj = app.modifyRawOomAdj(adj);
21653         app.curSchedGroup = schedGroup;
21654         app.curProcState = procState;
21655         app.foregroundActivities = foregroundActivities;
21656
21657         return app.curRawAdj;
21658     }
21659
21660     /**
21661      * Record new PSS sample for a process.
21662      */
21663     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21664             long now) {
21665         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21666                 swapPss * 1024);
21667         proc.lastPssTime = now;
21668         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21669         if (DEBUG_PSS) Slog.d(TAG_PSS,
21670                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21671                 + " state=" + ProcessList.makeProcStateString(procState));
21672         if (proc.initialIdlePss == 0) {
21673             proc.initialIdlePss = pss;
21674         }
21675         proc.lastPss = pss;
21676         proc.lastSwapPss = swapPss;
21677         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21678             proc.lastCachedPss = pss;
21679             proc.lastCachedSwapPss = swapPss;
21680         }
21681
21682         final SparseArray<Pair<Long, String>> watchUids
21683                 = mMemWatchProcesses.getMap().get(proc.processName);
21684         Long check = null;
21685         if (watchUids != null) {
21686             Pair<Long, String> val = watchUids.get(proc.uid);
21687             if (val == null) {
21688                 val = watchUids.get(0);
21689             }
21690             if (val != null) {
21691                 check = val.first;
21692             }
21693         }
21694         if (check != null) {
21695             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21696                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21697                 if (!isDebuggable) {
21698                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21699                         isDebuggable = true;
21700                     }
21701                 }
21702                 if (isDebuggable) {
21703                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21704                     final ProcessRecord myProc = proc;
21705                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21706                     mMemWatchDumpProcName = proc.processName;
21707                     mMemWatchDumpFile = heapdumpFile.toString();
21708                     mMemWatchDumpPid = proc.pid;
21709                     mMemWatchDumpUid = proc.uid;
21710                     BackgroundThread.getHandler().post(new Runnable() {
21711                         @Override
21712                         public void run() {
21713                             revokeUriPermission(ActivityThread.currentActivityThread()
21714                                             .getApplicationThread(),
21715                                     null, DumpHeapActivity.JAVA_URI,
21716                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21717                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21718                                     UserHandle.myUserId());
21719                             ParcelFileDescriptor fd = null;
21720                             try {
21721                                 heapdumpFile.delete();
21722                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21723                                         ParcelFileDescriptor.MODE_CREATE |
21724                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21725                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21726                                                 ParcelFileDescriptor.MODE_APPEND);
21727                                 IApplicationThread thread = myProc.thread;
21728                                 if (thread != null) {
21729                                     try {
21730                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21731                                                 "Requesting dump heap from "
21732                                                 + myProc + " to " + heapdumpFile);
21733                                         thread.dumpHeap(/* managed= */ true,
21734                                                 /* mallocInfo= */ false, /* runGc= */ false,
21735                                                 heapdumpFile.toString(), fd);
21736                                     } catch (RemoteException e) {
21737                                     }
21738                                 }
21739                             } catch (FileNotFoundException e) {
21740                                 e.printStackTrace();
21741                             } finally {
21742                                 if (fd != null) {
21743                                     try {
21744                                         fd.close();
21745                                     } catch (IOException e) {
21746                                     }
21747                                 }
21748                             }
21749                         }
21750                     });
21751                 } else {
21752                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21753                             + ", but debugging not enabled");
21754                 }
21755             }
21756         }
21757     }
21758
21759     /**
21760      * Schedule PSS collection of a process.
21761      */
21762     void requestPssLocked(ProcessRecord proc, int procState) {
21763         if (mPendingPssProcesses.contains(proc)) {
21764             return;
21765         }
21766         if (mPendingPssProcesses.size() == 0) {
21767             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21768         }
21769         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21770         proc.pssProcState = procState;
21771         mPendingPssProcesses.add(proc);
21772     }
21773
21774     /**
21775      * Schedule PSS collection of all processes.
21776      */
21777     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21778         if (!always) {
21779             if (now < (mLastFullPssTime +
21780                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21781                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21782                 return;
21783             }
21784         }
21785         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21786         mLastFullPssTime = now;
21787         mFullPssPending = true;
21788         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21789         mPendingPssProcesses.clear();
21790         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21791             ProcessRecord app = mLruProcesses.get(i);
21792             if (app.thread == null
21793                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21794                 continue;
21795             }
21796             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21797                 app.pssProcState = app.setProcState;
21798                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21799                         mTestPssMode, isSleepingLocked(), now);
21800                 mPendingPssProcesses.add(app);
21801             }
21802         }
21803         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21804     }
21805
21806     public void setTestPssMode(boolean enabled) {
21807         synchronized (this) {
21808             mTestPssMode = enabled;
21809             if (enabled) {
21810                 // Whenever we enable the mode, we want to take a snapshot all of current
21811                 // process mem use.
21812                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21813             }
21814         }
21815     }
21816
21817     /**
21818      * Ask a given process to GC right now.
21819      */
21820     final void performAppGcLocked(ProcessRecord app) {
21821         try {
21822             app.lastRequestedGc = SystemClock.uptimeMillis();
21823             if (app.thread != null) {
21824                 if (app.reportLowMemory) {
21825                     app.reportLowMemory = false;
21826                     app.thread.scheduleLowMemory();
21827                 } else {
21828                     app.thread.processInBackground();
21829                 }
21830             }
21831         } catch (Exception e) {
21832             // whatever.
21833         }
21834     }
21835
21836     /**
21837      * Returns true if things are idle enough to perform GCs.
21838      */
21839     private final boolean canGcNowLocked() {
21840         boolean processingBroadcasts = false;
21841         for (BroadcastQueue q : mBroadcastQueues) {
21842             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21843                 processingBroadcasts = true;
21844             }
21845         }
21846         return !processingBroadcasts
21847                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21848     }
21849
21850     /**
21851      * Perform GCs on all processes that are waiting for it, but only
21852      * if things are idle.
21853      */
21854     final void performAppGcsLocked() {
21855         final int N = mProcessesToGc.size();
21856         if (N <= 0) {
21857             return;
21858         }
21859         if (canGcNowLocked()) {
21860             while (mProcessesToGc.size() > 0) {
21861                 ProcessRecord proc = mProcessesToGc.remove(0);
21862                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21863                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21864                             <= SystemClock.uptimeMillis()) {
21865                         // To avoid spamming the system, we will GC processes one
21866                         // at a time, waiting a few seconds between each.
21867                         performAppGcLocked(proc);
21868                         scheduleAppGcsLocked();
21869                         return;
21870                     } else {
21871                         // It hasn't been long enough since we last GCed this
21872                         // process...  put it in the list to wait for its time.
21873                         addProcessToGcListLocked(proc);
21874                         break;
21875                     }
21876                 }
21877             }
21878
21879             scheduleAppGcsLocked();
21880         }
21881     }
21882
21883     /**
21884      * If all looks good, perform GCs on all processes waiting for them.
21885      */
21886     final void performAppGcsIfAppropriateLocked() {
21887         if (canGcNowLocked()) {
21888             performAppGcsLocked();
21889             return;
21890         }
21891         // Still not idle, wait some more.
21892         scheduleAppGcsLocked();
21893     }
21894
21895     /**
21896      * Schedule the execution of all pending app GCs.
21897      */
21898     final void scheduleAppGcsLocked() {
21899         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21900
21901         if (mProcessesToGc.size() > 0) {
21902             // Schedule a GC for the time to the next process.
21903             ProcessRecord proc = mProcessesToGc.get(0);
21904             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21905
21906             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21907             long now = SystemClock.uptimeMillis();
21908             if (when < (now+mConstants.GC_TIMEOUT)) {
21909                 when = now + mConstants.GC_TIMEOUT;
21910             }
21911             mHandler.sendMessageAtTime(msg, when);
21912         }
21913     }
21914
21915     /**
21916      * Add a process to the array of processes waiting to be GCed.  Keeps the
21917      * list in sorted order by the last GC time.  The process can't already be
21918      * on the list.
21919      */
21920     final void addProcessToGcListLocked(ProcessRecord proc) {
21921         boolean added = false;
21922         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21923             if (mProcessesToGc.get(i).lastRequestedGc <
21924                     proc.lastRequestedGc) {
21925                 added = true;
21926                 mProcessesToGc.add(i+1, proc);
21927                 break;
21928             }
21929         }
21930         if (!added) {
21931             mProcessesToGc.add(0, proc);
21932         }
21933     }
21934
21935     /**
21936      * Set up to ask a process to GC itself.  This will either do it
21937      * immediately, or put it on the list of processes to gc the next
21938      * time things are idle.
21939      */
21940     final void scheduleAppGcLocked(ProcessRecord app) {
21941         long now = SystemClock.uptimeMillis();
21942         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21943             return;
21944         }
21945         if (!mProcessesToGc.contains(app)) {
21946             addProcessToGcListLocked(app);
21947             scheduleAppGcsLocked();
21948         }
21949     }
21950
21951     final void checkExcessivePowerUsageLocked() {
21952         updateCpuStatsNow();
21953
21954         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21955         boolean doCpuKills = true;
21956         if (mLastPowerCheckUptime == 0) {
21957             doCpuKills = false;
21958         }
21959         final long curUptime = SystemClock.uptimeMillis();
21960         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21961         mLastPowerCheckUptime = curUptime;
21962         int i = mLruProcesses.size();
21963         while (i > 0) {
21964             i--;
21965             ProcessRecord app = mLruProcesses.get(i);
21966             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21967                 if (app.lastCpuTime <= 0) {
21968                     continue;
21969                 }
21970                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21971                 if (DEBUG_POWER) {
21972                     StringBuilder sb = new StringBuilder(128);
21973                     sb.append("CPU for ");
21974                     app.toShortString(sb);
21975                     sb.append(": over ");
21976                     TimeUtils.formatDuration(uptimeSince, sb);
21977                     sb.append(" used ");
21978                     TimeUtils.formatDuration(cputimeUsed, sb);
21979                     sb.append(" (");
21980                     sb.append((cputimeUsed*100)/uptimeSince);
21981                     sb.append("%)");
21982                     Slog.i(TAG_POWER, sb.toString());
21983                 }
21984                 // If the process has used too much CPU over the last duration, the
21985                 // user probably doesn't want this, so kill!
21986                 if (doCpuKills && uptimeSince > 0) {
21987                     // What is the limit for this process?
21988                     int cpuLimit;
21989                     long checkDur = curUptime - app.whenUnimportant;
21990                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21991                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21992                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21993                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21994                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21995                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21996                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
21997                     } else {
21998                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
21999                     }
22000                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22001                         synchronized (stats) {
22002                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22003                                     uptimeSince, cputimeUsed);
22004                         }
22005                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22006                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22007                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22008                     }
22009                 }
22010                 app.lastCpuTime = app.curCpuTime;
22011             }
22012         }
22013     }
22014
22015     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22016             long nowElapsed) {
22017         boolean success = true;
22018
22019         if (app.curRawAdj != app.setRawAdj) {
22020             app.setRawAdj = app.curRawAdj;
22021         }
22022
22023         int changes = 0;
22024
22025         if (app.curAdj != app.setAdj) {
22026             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22027             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22028                 String msg = "Set " + app.pid + " " + app.processName + " adj "
22029                         + app.curAdj + ": " + app.adjType;
22030                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22031             }
22032             app.setAdj = app.curAdj;
22033             app.verifiedAdj = ProcessList.INVALID_ADJ;
22034         }
22035
22036         if (app.setSchedGroup != app.curSchedGroup) {
22037             int oldSchedGroup = app.setSchedGroup;
22038             app.setSchedGroup = app.curSchedGroup;
22039             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22040                 String msg = "Setting sched group of " + app.processName
22041                         + " to " + app.curSchedGroup;
22042                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22043             }
22044             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22045                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22046                 app.kill(app.waitingToKill, true);
22047                 success = false;
22048             } else {
22049                 int processGroup;
22050                 switch (app.curSchedGroup) {
22051                     case ProcessList.SCHED_GROUP_BACKGROUND:
22052                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22053                         break;
22054                     case ProcessList.SCHED_GROUP_TOP_APP:
22055                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22056                         processGroup = THREAD_GROUP_TOP_APP;
22057                         break;
22058                     default:
22059                         processGroup = THREAD_GROUP_DEFAULT;
22060                         break;
22061                 }
22062                 long oldId = Binder.clearCallingIdentity();
22063                 try {
22064                     setProcessGroup(app.pid, processGroup);
22065                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22066                         // do nothing if we already switched to RT
22067                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22068                             mVrController.onTopProcChangedLocked(app);
22069                             if (mUseFifoUiScheduling) {
22070                                 // Switch UI pipeline for app to SCHED_FIFO
22071                                 app.savedPriority = Process.getThreadPriority(app.pid);
22072                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22073                                 if (app.renderThreadTid != 0) {
22074                                     scheduleAsFifoPriority(app.renderThreadTid,
22075                                         /* suppressLogs */true);
22076                                     if (DEBUG_OOM_ADJ) {
22077                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22078                                             app.renderThreadTid + ") to FIFO");
22079                                     }
22080                                 } else {
22081                                     if (DEBUG_OOM_ADJ) {
22082                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22083                                     }
22084                                 }
22085                             } else {
22086                                 // Boost priority for top app UI and render threads
22087                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22088                                 if (app.renderThreadTid != 0) {
22089                                     try {
22090                                         setThreadPriority(app.renderThreadTid,
22091                                                 TOP_APP_PRIORITY_BOOST);
22092                                     } catch (IllegalArgumentException e) {
22093                                         // thread died, ignore
22094                                     }
22095                                 }
22096                             }
22097                         }
22098                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22099                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22100                         mVrController.onTopProcChangedLocked(app);
22101                         if (mUseFifoUiScheduling) {
22102                             try {
22103                                 // Reset UI pipeline to SCHED_OTHER
22104                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22105                                 setThreadPriority(app.pid, app.savedPriority);
22106                                 if (app.renderThreadTid != 0) {
22107                                     setThreadScheduler(app.renderThreadTid,
22108                                         SCHED_OTHER, 0);
22109                                     setThreadPriority(app.renderThreadTid, -4);
22110                                 }
22111                             } catch (IllegalArgumentException e) {
22112                                 Slog.w(TAG,
22113                                         "Failed to set scheduling policy, thread does not exist:\n"
22114                                                 + e);
22115                             } catch (SecurityException e) {
22116                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22117                             }
22118                         } else {
22119                             // Reset priority for top app UI and render threads
22120                             setThreadPriority(app.pid, 0);
22121                             if (app.renderThreadTid != 0) {
22122                                 setThreadPriority(app.renderThreadTid, 0);
22123                             }
22124                         }
22125                     }
22126                 } catch (Exception e) {
22127                     if (false) {
22128                         Slog.w(TAG, "Failed setting process group of " + app.pid
22129                                 + " to " + app.curSchedGroup);
22130                         Slog.w(TAG, "at location", e);
22131                     }
22132                 } finally {
22133                     Binder.restoreCallingIdentity(oldId);
22134                 }
22135             }
22136         }
22137         if (app.repForegroundActivities != app.foregroundActivities) {
22138             app.repForegroundActivities = app.foregroundActivities;
22139             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22140         }
22141         if (app.repProcState != app.curProcState) {
22142             app.repProcState = app.curProcState;
22143             if (app.thread != null) {
22144                 try {
22145                     if (false) {
22146                         //RuntimeException h = new RuntimeException("here");
22147                         Slog.i(TAG, "Sending new process state " + app.repProcState
22148                                 + " to " + app /*, h*/);
22149                     }
22150                     app.thread.setProcessState(app.repProcState);
22151                 } catch (RemoteException e) {
22152                 }
22153             }
22154         }
22155         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22156                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22157             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22158                 // Experimental code to more aggressively collect pss while
22159                 // running test...  the problem is that this tends to collect
22160                 // the data right when a process is transitioning between process
22161                 // states, which well tend to give noisy data.
22162                 long start = SystemClock.uptimeMillis();
22163                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22164                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22165                 mPendingPssProcesses.remove(app);
22166                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22167                         + " to " + app.curProcState + ": "
22168                         + (SystemClock.uptimeMillis()-start) + "ms");
22169             }
22170             app.lastStateTime = now;
22171             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22172                     mTestPssMode, isSleepingLocked(), now);
22173             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22174                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22175                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22176                     + (app.nextPssTime-now) + ": " + app);
22177         } else {
22178             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22179                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22180                     mTestPssMode)))) {
22181                 requestPssLocked(app, app.setProcState);
22182                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22183                         mTestPssMode, isSleepingLocked(), now);
22184             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22185                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22186         }
22187         if (app.setProcState != app.curProcState) {
22188             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22189                 String msg = "Proc state change of " + app.processName
22190                         + " to " + app.curProcState;
22191                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22192             }
22193             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22194             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22195             if (setImportant && !curImportant) {
22196                 // This app is no longer something we consider important enough to allow to
22197                 // use arbitrary amounts of battery power.  Note
22198                 // its current CPU time to later know to kill it if
22199                 // it is not behaving well.
22200                 app.whenUnimportant = now;
22201                 app.lastCpuTime = 0;
22202             }
22203             // Inform UsageStats of important process state change
22204             // Must be called before updating setProcState
22205             maybeUpdateUsageStatsLocked(app, nowElapsed);
22206
22207             app.setProcState = app.curProcState;
22208             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22209                 app.notCachedSinceIdle = false;
22210             }
22211             if (!doingAll) {
22212                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22213             } else {
22214                 app.procStateChanged = true;
22215             }
22216         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22217                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22218             // For apps that sit around for a long time in the interactive state, we need
22219             // to report this at least once a day so they don't go idle.
22220             maybeUpdateUsageStatsLocked(app, nowElapsed);
22221         }
22222
22223         if (changes != 0) {
22224             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22225                     "Changes in " + app + ": " + changes);
22226             int i = mPendingProcessChanges.size()-1;
22227             ProcessChangeItem item = null;
22228             while (i >= 0) {
22229                 item = mPendingProcessChanges.get(i);
22230                 if (item.pid == app.pid) {
22231                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22232                             "Re-using existing item: " + item);
22233                     break;
22234                 }
22235                 i--;
22236             }
22237             if (i < 0) {
22238                 // No existing item in pending changes; need a new one.
22239                 final int NA = mAvailProcessChanges.size();
22240                 if (NA > 0) {
22241                     item = mAvailProcessChanges.remove(NA-1);
22242                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22243                             "Retrieving available item: " + item);
22244                 } else {
22245                     item = new ProcessChangeItem();
22246                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22247                             "Allocating new item: " + item);
22248                 }
22249                 item.changes = 0;
22250                 item.pid = app.pid;
22251                 item.uid = app.info.uid;
22252                 if (mPendingProcessChanges.size() == 0) {
22253                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22254                             "*** Enqueueing dispatch processes changed!");
22255                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22256                 }
22257                 mPendingProcessChanges.add(item);
22258             }
22259             item.changes |= changes;
22260             item.foregroundActivities = app.repForegroundActivities;
22261             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22262                     "Item " + Integer.toHexString(System.identityHashCode(item))
22263                     + " " + app.toShortString() + ": changes=" + item.changes
22264                     + " foreground=" + item.foregroundActivities
22265                     + " type=" + app.adjType + " source=" + app.adjSource
22266                     + " target=" + app.adjTarget);
22267         }
22268
22269         return success;
22270     }
22271
22272     private boolean isEphemeralLocked(int uid) {
22273         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22274         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22275             return false;
22276         }
22277         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22278                 packages[0]);
22279     }
22280
22281     @VisibleForTesting
22282     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22283         final UidRecord.ChangeItem pendingChange;
22284         if (uidRec == null || uidRec.pendingChange == null) {
22285             if (mPendingUidChanges.size() == 0) {
22286                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22287                         "*** Enqueueing dispatch uid changed!");
22288                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22289             }
22290             final int NA = mAvailUidChanges.size();
22291             if (NA > 0) {
22292                 pendingChange = mAvailUidChanges.remove(NA-1);
22293                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22294                         "Retrieving available item: " + pendingChange);
22295             } else {
22296                 pendingChange = new UidRecord.ChangeItem();
22297                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22298                         "Allocating new item: " + pendingChange);
22299             }
22300             if (uidRec != null) {
22301                 uidRec.pendingChange = pendingChange;
22302                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22303                     // If this uid is going away, and we haven't yet reported it is gone,
22304                     // then do so now.
22305                     change |= UidRecord.CHANGE_IDLE;
22306                 }
22307             } else if (uid < 0) {
22308                 throw new IllegalArgumentException("No UidRecord or uid");
22309             }
22310             pendingChange.uidRecord = uidRec;
22311             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22312             mPendingUidChanges.add(pendingChange);
22313         } else {
22314             pendingChange = uidRec.pendingChange;
22315             // If there is no change in idle or active state, then keep whatever was pending.
22316             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22317                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22318                         | UidRecord.CHANGE_ACTIVE));
22319             }
22320             // If there is no change in cached or uncached state, then keep whatever was pending.
22321             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22322                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22323                         | UidRecord.CHANGE_UNCACHED));
22324             }
22325             // If this is a report of the UID being gone, then we shouldn't keep any previous
22326             // report of it being active or cached.  (That is, a gone uid is never active,
22327             // and never cached.)
22328             if ((change & UidRecord.CHANGE_GONE) != 0) {
22329                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22330                 if (!uidRec.idle) {
22331                     // If this uid is going away, and we haven't yet reported it is gone,
22332                     // then do so now.
22333                     change |= UidRecord.CHANGE_IDLE;
22334                 }
22335             }
22336         }
22337         pendingChange.change = change;
22338         pendingChange.processState = uidRec != null
22339                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22340         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22341         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22342         if (uidRec != null) {
22343             uidRec.lastReportedChange = change;
22344             uidRec.updateLastDispatchedProcStateSeq(change);
22345         }
22346
22347         // Directly update the power manager, since we sit on top of it and it is critical
22348         // it be kept in sync (so wake locks will be held as soon as appropriate).
22349         if (mLocalPowerManager != null) {
22350             // TO DO: dispatch cached/uncached changes here, so we don't need to report
22351             // all proc state changes.
22352             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22353                 mLocalPowerManager.uidActive(pendingChange.uid);
22354             }
22355             if ((change & UidRecord.CHANGE_IDLE) != 0) {
22356                 mLocalPowerManager.uidIdle(pendingChange.uid);
22357             }
22358             if ((change & UidRecord.CHANGE_GONE) != 0) {
22359                 mLocalPowerManager.uidGone(pendingChange.uid);
22360             } else {
22361                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22362                         pendingChange.processState);
22363             }
22364         }
22365     }
22366
22367     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22368             String authority) {
22369         if (app == null) return;
22370         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22371             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22372             if (userState == null) return;
22373             final long now = SystemClock.elapsedRealtime();
22374             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22375             if (lastReported == null || lastReported < now - 60 * 1000L) {
22376                 if (mSystemReady) {
22377                     // Cannot touch the user stats if not system ready
22378                     mUsageStatsService.reportContentProviderUsage(
22379                             authority, providerPkgName, app.userId);
22380                 }
22381                 userState.mProviderLastReportedFg.put(authority, now);
22382             }
22383         }
22384     }
22385
22386     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22387         if (DEBUG_USAGE_STATS) {
22388             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22389                     + "] state changes: old = " + app.setProcState + ", new = "
22390                     + app.curProcState);
22391         }
22392         if (mUsageStatsService == null) {
22393             return;
22394         }
22395         boolean isInteraction;
22396         // To avoid some abuse patterns, we are going to be careful about what we consider
22397         // to be an app interaction.  Being the top activity doesn't count while the display
22398         // is sleeping, nor do short foreground services.
22399         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22400             isInteraction = true;
22401             app.fgInteractionTime = 0;
22402         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22403             if (app.fgInteractionTime == 0) {
22404                 app.fgInteractionTime = nowElapsed;
22405                 isInteraction = false;
22406             } else {
22407                 isInteraction = nowElapsed > app.fgInteractionTime
22408                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22409             }
22410         } else {
22411             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22412             app.fgInteractionTime = 0;
22413         }
22414         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22415                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22416             app.interactionEventTime = nowElapsed;
22417             String[] packages = app.getPackageList();
22418             if (packages != null) {
22419                 for (int i = 0; i < packages.length; i++) {
22420                     mUsageStatsService.reportEvent(packages[i], app.userId,
22421                             UsageEvents.Event.SYSTEM_INTERACTION);
22422                 }
22423             }
22424         }
22425         app.reportedInteraction = isInteraction;
22426         if (!isInteraction) {
22427             app.interactionEventTime = 0;
22428         }
22429     }
22430
22431     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22432         if (proc.thread != null) {
22433             if (proc.baseProcessTracker != null) {
22434                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22435             }
22436         }
22437     }
22438
22439     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22440             ProcessRecord TOP_APP, boolean doingAll, long now) {
22441         if (app.thread == null) {
22442             return false;
22443         }
22444
22445         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22446
22447         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22448     }
22449
22450     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22451             boolean oomAdj) {
22452         if (isForeground != proc.foregroundServices) {
22453             proc.foregroundServices = isForeground;
22454             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22455                     proc.info.uid);
22456             if (isForeground) {
22457                 if (curProcs == null) {
22458                     curProcs = new ArrayList<ProcessRecord>();
22459                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22460                 }
22461                 if (!curProcs.contains(proc)) {
22462                     curProcs.add(proc);
22463                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22464                             proc.info.packageName, proc.info.uid);
22465                 }
22466             } else {
22467                 if (curProcs != null) {
22468                     if (curProcs.remove(proc)) {
22469                         mBatteryStatsService.noteEvent(
22470                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22471                                 proc.info.packageName, proc.info.uid);
22472                         if (curProcs.size() <= 0) {
22473                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22474                         }
22475                     }
22476                 }
22477             }
22478             if (oomAdj) {
22479                 updateOomAdjLocked();
22480             }
22481         }
22482     }
22483
22484     private final ActivityRecord resumedAppLocked() {
22485         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22486         String pkg;
22487         int uid;
22488         if (act != null) {
22489             pkg = act.packageName;
22490             uid = act.info.applicationInfo.uid;
22491         } else {
22492             pkg = null;
22493             uid = -1;
22494         }
22495         // Has the UID or resumed package name changed?
22496         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22497                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22498             if (mCurResumedPackage != null) {
22499                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22500                         mCurResumedPackage, mCurResumedUid);
22501             }
22502             mCurResumedPackage = pkg;
22503             mCurResumedUid = uid;
22504             if (mCurResumedPackage != null) {
22505                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22506                         mCurResumedPackage, mCurResumedUid);
22507             }
22508         }
22509         return act;
22510     }
22511
22512     /**
22513      * Update OomAdj for a specific process.
22514      * @param app The process to update
22515      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22516      *                  if necessary, or skip.
22517      * @return whether updateOomAdjLocked(app) was successful.
22518      */
22519     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22520         final ActivityRecord TOP_ACT = resumedAppLocked();
22521         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22522         final boolean wasCached = app.cached;
22523
22524         mAdjSeq++;
22525
22526         // This is the desired cached adjusment we want to tell it to use.
22527         // If our app is currently cached, we know it, and that is it.  Otherwise,
22528         // we don't know it yet, and it needs to now be cached we will then
22529         // need to do a complete oom adj.
22530         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22531                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22532         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22533                 SystemClock.uptimeMillis());
22534         if (oomAdjAll
22535                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22536             // Changed to/from cached state, so apps after it in the LRU
22537             // list may also be changed.
22538             updateOomAdjLocked();
22539         }
22540         return success;
22541     }
22542
22543     final void updateOomAdjLocked() {
22544         final ActivityRecord TOP_ACT = resumedAppLocked();
22545         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22546         final long now = SystemClock.uptimeMillis();
22547         final long nowElapsed = SystemClock.elapsedRealtime();
22548         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22549         final int N = mLruProcesses.size();
22550
22551         if (false) {
22552             RuntimeException e = new RuntimeException();
22553             e.fillInStackTrace();
22554             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22555         }
22556
22557         // Reset state in all uid records.
22558         for (int i=mActiveUids.size()-1; i>=0; i--) {
22559             final UidRecord uidRec = mActiveUids.valueAt(i);
22560             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22561                     "Starting update of " + uidRec);
22562             uidRec.reset();
22563         }
22564
22565         mStackSupervisor.rankTaskLayersIfNeeded();
22566
22567         mAdjSeq++;
22568         mNewNumServiceProcs = 0;
22569         mNewNumAServiceProcs = 0;
22570
22571         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22572         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22573
22574         // Let's determine how many processes we have running vs.
22575         // how many slots we have for background processes; we may want
22576         // to put multiple processes in a slot of there are enough of
22577         // them.
22578         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22579                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22580         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22581         if (numEmptyProcs > cachedProcessLimit) {
22582             // If there are more empty processes than our limit on cached
22583             // processes, then use the cached process limit for the factor.
22584             // This ensures that the really old empty processes get pushed
22585             // down to the bottom, so if we are running low on memory we will
22586             // have a better chance at keeping around more cached processes
22587             // instead of a gazillion empty processes.
22588             numEmptyProcs = cachedProcessLimit;
22589         }
22590         int emptyFactor = numEmptyProcs/numSlots;
22591         if (emptyFactor < 1) emptyFactor = 1;
22592         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22593         if (cachedFactor < 1) cachedFactor = 1;
22594         int stepCached = 0;
22595         int stepEmpty = 0;
22596         int numCached = 0;
22597         int numEmpty = 0;
22598         int numTrimming = 0;
22599
22600         mNumNonCachedProcs = 0;
22601         mNumCachedHiddenProcs = 0;
22602
22603         // First update the OOM adjustment for each of the
22604         // application processes based on their current state.
22605         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22606         int nextCachedAdj = curCachedAdj+1;
22607         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22608         int nextEmptyAdj = curEmptyAdj+2;
22609         for (int i=N-1; i>=0; i--) {
22610             ProcessRecord app = mLruProcesses.get(i);
22611             if (!app.killedByAm && app.thread != null) {
22612                 app.procStateChanged = false;
22613                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22614
22615                 // If we haven't yet assigned the final cached adj
22616                 // to the process, do that now.
22617                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22618                     switch (app.curProcState) {
22619                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22620                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22621                             // This process is a cached process holding activities...
22622                             // assign it the next cached value for that type, and then
22623                             // step that cached level.
22624                             app.curRawAdj = curCachedAdj;
22625                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22626                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22627                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22628                                     + ")");
22629                             if (curCachedAdj != nextCachedAdj) {
22630                                 stepCached++;
22631                                 if (stepCached >= cachedFactor) {
22632                                     stepCached = 0;
22633                                     curCachedAdj = nextCachedAdj;
22634                                     nextCachedAdj += 2;
22635                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22636                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22637                                     }
22638                                 }
22639                             }
22640                             break;
22641                         default:
22642                             // For everything else, assign next empty cached process
22643                             // level and bump that up.  Note that this means that
22644                             // long-running services that have dropped down to the
22645                             // cached level will be treated as empty (since their process
22646                             // state is still as a service), which is what we want.
22647                             app.curRawAdj = curEmptyAdj;
22648                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22649                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22650                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22651                                     + ")");
22652                             if (curEmptyAdj != nextEmptyAdj) {
22653                                 stepEmpty++;
22654                                 if (stepEmpty >= emptyFactor) {
22655                                     stepEmpty = 0;
22656                                     curEmptyAdj = nextEmptyAdj;
22657                                     nextEmptyAdj += 2;
22658                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22659                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22660                                     }
22661                                 }
22662                             }
22663                             break;
22664                     }
22665                 }
22666
22667                 applyOomAdjLocked(app, true, now, nowElapsed);
22668
22669                 // Count the number of process types.
22670                 switch (app.curProcState) {
22671                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22672                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22673                         mNumCachedHiddenProcs++;
22674                         numCached++;
22675                         if (numCached > cachedProcessLimit) {
22676                             app.kill("cached #" + numCached, true);
22677                         }
22678                         break;
22679                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22680                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22681                                 && app.lastActivityTime < oldTime) {
22682                             app.kill("empty for "
22683                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22684                                     / 1000) + "s", true);
22685                         } else {
22686                             numEmpty++;
22687                             if (numEmpty > emptyProcessLimit) {
22688                                 app.kill("empty #" + numEmpty, true);
22689                             }
22690                         }
22691                         break;
22692                     default:
22693                         mNumNonCachedProcs++;
22694                         break;
22695                 }
22696
22697                 if (app.isolated && app.services.size() <= 0) {
22698                     // If this is an isolated process, and there are no
22699                     // services running in it, then the process is no longer
22700                     // needed.  We agressively kill these because we can by
22701                     // definition not re-use the same process again, and it is
22702                     // good to avoid having whatever code was running in them
22703                     // left sitting around after no longer needed.
22704                     app.kill("isolated not needed", true);
22705                 } else {
22706                     // Keeping this process, update its uid.
22707                     final UidRecord uidRec = app.uidRecord;
22708                     if (uidRec != null) {
22709                         uidRec.ephemeral = app.info.isInstantApp();
22710                         if (uidRec.curProcState > app.curProcState) {
22711                             uidRec.curProcState = app.curProcState;
22712                         }
22713                         if (app.foregroundServices) {
22714                             uidRec.foregroundServices = true;
22715                         }
22716                     }
22717                 }
22718
22719                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22720                         && !app.killedByAm) {
22721                     numTrimming++;
22722                 }
22723             }
22724         }
22725
22726         incrementProcStateSeqAndNotifyAppsLocked();
22727
22728         mNumServiceProcs = mNewNumServiceProcs;
22729
22730         // Now determine the memory trimming level of background processes.
22731         // Unfortunately we need to start at the back of the list to do this
22732         // properly.  We only do this if the number of background apps we
22733         // are managing to keep around is less than half the maximum we desire;
22734         // if we are keeping a good number around, we'll let them use whatever
22735         // memory they want.
22736         final int numCachedAndEmpty = numCached + numEmpty;
22737         int memFactor;
22738         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22739                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22740             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22741                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22742             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22743                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22744             } else {
22745                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22746             }
22747         } else {
22748             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22749         }
22750         // We always allow the memory level to go up (better).  We only allow it to go
22751         // down if we are in a state where that is allowed, *and* the total number of processes
22752         // has gone down since last time.
22753         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22754                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22755                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22756         if (memFactor > mLastMemoryLevel) {
22757             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22758                 memFactor = mLastMemoryLevel;
22759                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22760             }
22761         }
22762         if (memFactor != mLastMemoryLevel) {
22763             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22764         }
22765         mLastMemoryLevel = memFactor;
22766         mLastNumProcesses = mLruProcesses.size();
22767         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22768         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22769         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22770             if (mLowRamStartTime == 0) {
22771                 mLowRamStartTime = now;
22772             }
22773             int step = 0;
22774             int fgTrimLevel;
22775             switch (memFactor) {
22776                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22777                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22778                     break;
22779                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22780                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22781                     break;
22782                 default:
22783                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22784                     break;
22785             }
22786             int factor = numTrimming/3;
22787             int minFactor = 2;
22788             if (mHomeProcess != null) minFactor++;
22789             if (mPreviousProcess != null) minFactor++;
22790             if (factor < minFactor) factor = minFactor;
22791             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22792             for (int i=N-1; i>=0; i--) {
22793                 ProcessRecord app = mLruProcesses.get(i);
22794                 if (allChanged || app.procStateChanged) {
22795                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22796                     app.procStateChanged = false;
22797                 }
22798                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22799                         && !app.killedByAm) {
22800                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22801                         try {
22802                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22803                                     "Trimming memory of " + app.processName + " to " + curLevel);
22804                             app.thread.scheduleTrimMemory(curLevel);
22805                         } catch (RemoteException e) {
22806                         }
22807                         if (false) {
22808                             // For now we won't do this; our memory trimming seems
22809                             // to be good enough at this point that destroying
22810                             // activities causes more harm than good.
22811                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22812                                     && app != mHomeProcess && app != mPreviousProcess) {
22813                                 // Need to do this on its own message because the stack may not
22814                                 // be in a consistent state at this point.
22815                                 // For these apps we will also finish their activities
22816                                 // to help them free memory.
22817                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22818                             }
22819                         }
22820                     }
22821                     app.trimMemoryLevel = curLevel;
22822                     step++;
22823                     if (step >= factor) {
22824                         step = 0;
22825                         switch (curLevel) {
22826                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22827                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22828                                 break;
22829                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22830                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22831                                 break;
22832                         }
22833                     }
22834                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22835                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22836                             && app.thread != null) {
22837                         try {
22838                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22839                                     "Trimming memory of heavy-weight " + app.processName
22840                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22841                             app.thread.scheduleTrimMemory(
22842                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22843                         } catch (RemoteException e) {
22844                         }
22845                     }
22846                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22847                 } else {
22848                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22849                             || app.systemNoUi) && app.pendingUiClean) {
22850                         // If this application is now in the background and it
22851                         // had done UI, then give it the special trim level to
22852                         // have it free UI resources.
22853                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22854                         if (app.trimMemoryLevel < level && app.thread != null) {
22855                             try {
22856                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22857                                         "Trimming memory of bg-ui " + app.processName
22858                                         + " to " + level);
22859                                 app.thread.scheduleTrimMemory(level);
22860                             } catch (RemoteException e) {
22861                             }
22862                         }
22863                         app.pendingUiClean = false;
22864                     }
22865                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22866                         try {
22867                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22868                                     "Trimming memory of fg " + app.processName
22869                                     + " to " + fgTrimLevel);
22870                             app.thread.scheduleTrimMemory(fgTrimLevel);
22871                         } catch (RemoteException e) {
22872                         }
22873                     }
22874                     app.trimMemoryLevel = fgTrimLevel;
22875                 }
22876             }
22877         } else {
22878             if (mLowRamStartTime != 0) {
22879                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22880                 mLowRamStartTime = 0;
22881             }
22882             for (int i=N-1; i>=0; i--) {
22883                 ProcessRecord app = mLruProcesses.get(i);
22884                 if (allChanged || app.procStateChanged) {
22885                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22886                     app.procStateChanged = false;
22887                 }
22888                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22889                         || app.systemNoUi) && app.pendingUiClean) {
22890                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22891                             && app.thread != null) {
22892                         try {
22893                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22894                                     "Trimming memory of ui hidden " + app.processName
22895                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22896                             app.thread.scheduleTrimMemory(
22897                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22898                         } catch (RemoteException e) {
22899                         }
22900                     }
22901                     app.pendingUiClean = false;
22902                 }
22903                 app.trimMemoryLevel = 0;
22904             }
22905         }
22906
22907         if (mAlwaysFinishActivities) {
22908             // Need to do this on its own message because the stack may not
22909             // be in a consistent state at this point.
22910             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22911         }
22912
22913         if (allChanged) {
22914             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22915         }
22916
22917         ArrayList<UidRecord> becameIdle = null;
22918
22919         // Update from any uid changes.
22920         if (mLocalPowerManager != null) {
22921             mLocalPowerManager.startUidChanges();
22922         }
22923         for (int i=mActiveUids.size()-1; i>=0; i--) {
22924             final UidRecord uidRec = mActiveUids.valueAt(i);
22925             int uidChange = UidRecord.CHANGE_PROCSTATE;
22926             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22927                     && (uidRec.setProcState != uidRec.curProcState
22928                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
22929                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22930                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22931                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22932                         + " to " + uidRec.curWhitelist);
22933                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22934                         && !uidRec.curWhitelist) {
22935                     // UID is now in the background (and not on the temp whitelist).  Was it
22936                     // previously in the foreground (or on the temp whitelist)?
22937                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22938                             || uidRec.setWhitelist) {
22939                         uidRec.lastBackgroundTime = nowElapsed;
22940                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22941                             // Note: the background settle time is in elapsed realtime, while
22942                             // the handler time base is uptime.  All this means is that we may
22943                             // stop background uids later than we had intended, but that only
22944                             // happens because the device was sleeping so we are okay anyway.
22945                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22946                                     mConstants.BACKGROUND_SETTLE_TIME);
22947                         }
22948                     }
22949                     if (uidRec.idle && !uidRec.setIdle) {
22950                         uidChange = UidRecord.CHANGE_IDLE;
22951                         if (becameIdle == null) {
22952                             becameIdle = new ArrayList<>();
22953                         }
22954                         becameIdle.add(uidRec);
22955                     }
22956                 } else {
22957                     if (uidRec.idle) {
22958                         uidChange = UidRecord.CHANGE_ACTIVE;
22959                         EventLogTags.writeAmUidActive(uidRec.uid);
22960                         uidRec.idle = false;
22961                     }
22962                     uidRec.lastBackgroundTime = 0;
22963                 }
22964                 final boolean wasCached = uidRec.setProcState
22965                         > ActivityManager.PROCESS_STATE_RECEIVER;
22966                 final boolean isCached = uidRec.curProcState
22967                         > ActivityManager.PROCESS_STATE_RECEIVER;
22968                 if (wasCached != isCached ||
22969                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22970                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22971                 }
22972                 uidRec.setProcState = uidRec.curProcState;
22973                 uidRec.setWhitelist = uidRec.curWhitelist;
22974                 uidRec.setIdle = uidRec.idle;
22975                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22976                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22977                 if (uidRec.foregroundServices) {
22978                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22979                 }
22980             }
22981         }
22982         if (mLocalPowerManager != null) {
22983             mLocalPowerManager.finishUidChanges();
22984         }
22985
22986         if (becameIdle != null) {
22987             // If we have any new uids that became idle this time, we need to make sure
22988             // they aren't left with running services.
22989             for (int i = becameIdle.size() - 1; i >= 0; i--) {
22990                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22991             }
22992         }
22993
22994         if (mProcessStats.shouldWriteNowLocked(now)) {
22995             mHandler.post(new Runnable() {
22996                 @Override public void run() {
22997                     synchronized (ActivityManagerService.this) {
22998                         mProcessStats.writeStateAsyncLocked();
22999                     }
23000                 }
23001             });
23002         }
23003
23004         if (DEBUG_OOM_ADJ) {
23005             final long duration = SystemClock.uptimeMillis() - now;
23006             if (false) {
23007                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23008                         new RuntimeException("here").fillInStackTrace());
23009             } else {
23010                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23011             }
23012         }
23013     }
23014
23015     @Override
23016     public void makePackageIdle(String packageName, int userId) {
23017         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23018                 != PackageManager.PERMISSION_GRANTED) {
23019             String msg = "Permission Denial: makePackageIdle() from pid="
23020                     + Binder.getCallingPid()
23021                     + ", uid=" + Binder.getCallingUid()
23022                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23023             Slog.w(TAG, msg);
23024             throw new SecurityException(msg);
23025         }
23026         final int callingPid = Binder.getCallingPid();
23027         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23028                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23029         long callingId = Binder.clearCallingIdentity();
23030         synchronized(this) {
23031             try {
23032                 IPackageManager pm = AppGlobals.getPackageManager();
23033                 int pkgUid = -1;
23034                 try {
23035                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23036                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23037                 } catch (RemoteException e) {
23038                 }
23039                 if (pkgUid == -1) {
23040                     throw new IllegalArgumentException("Unknown package name " + packageName);
23041                 }
23042
23043                 if (mLocalPowerManager != null) {
23044                     mLocalPowerManager.startUidChanges();
23045                 }
23046                 final int appId = UserHandle.getAppId(pkgUid);
23047                 final int N = mActiveUids.size();
23048                 for (int i=N-1; i>=0; i--) {
23049                     final UidRecord uidRec = mActiveUids.valueAt(i);
23050                     final long bgTime = uidRec.lastBackgroundTime;
23051                     if (bgTime > 0 && !uidRec.idle) {
23052                         if (UserHandle.getAppId(uidRec.uid) == appId) {
23053                             if (userId == UserHandle.USER_ALL ||
23054                                     userId == UserHandle.getUserId(uidRec.uid)) {
23055                                 EventLogTags.writeAmUidIdle(uidRec.uid);
23056                                 uidRec.idle = true;
23057                                 uidRec.setIdle = true;
23058                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23059                                         + " from package " + packageName + " user " + userId);
23060                                 doStopUidLocked(uidRec.uid, uidRec);
23061                             }
23062                         }
23063                     }
23064                 }
23065             } finally {
23066                 if (mLocalPowerManager != null) {
23067                     mLocalPowerManager.finishUidChanges();
23068                 }
23069                 Binder.restoreCallingIdentity(callingId);
23070             }
23071         }
23072     }
23073
23074     final void idleUids() {
23075         synchronized (this) {
23076             final int N = mActiveUids.size();
23077             if (N <= 0) {
23078                 return;
23079             }
23080             final long nowElapsed = SystemClock.elapsedRealtime();
23081             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23082             long nextTime = 0;
23083             if (mLocalPowerManager != null) {
23084                 mLocalPowerManager.startUidChanges();
23085             }
23086             for (int i=N-1; i>=0; i--) {
23087                 final UidRecord uidRec = mActiveUids.valueAt(i);
23088                 final long bgTime = uidRec.lastBackgroundTime;
23089                 if (bgTime > 0 && !uidRec.idle) {
23090                     if (bgTime <= maxBgTime) {
23091                         EventLogTags.writeAmUidIdle(uidRec.uid);
23092                         uidRec.idle = true;
23093                         uidRec.setIdle = true;
23094                         doStopUidLocked(uidRec.uid, uidRec);
23095                     } else {
23096                         if (nextTime == 0 || nextTime > bgTime) {
23097                             nextTime = bgTime;
23098                         }
23099                     }
23100                 }
23101             }
23102             if (mLocalPowerManager != null) {
23103                 mLocalPowerManager.finishUidChanges();
23104             }
23105             if (nextTime > 0) {
23106                 mHandler.removeMessages(IDLE_UIDS_MSG);
23107                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23108                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23109             }
23110         }
23111     }
23112
23113     /**
23114      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23115      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23116      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23117      */
23118     @VisibleForTesting
23119     @GuardedBy("this")
23120     void incrementProcStateSeqAndNotifyAppsLocked() {
23121         if (mWaitForNetworkTimeoutMs <= 0) {
23122             return;
23123         }
23124         // Used for identifying which uids need to block for network.
23125         ArrayList<Integer> blockingUids = null;
23126         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23127             final UidRecord uidRec = mActiveUids.valueAt(i);
23128             // If the network is not restricted for uid, then nothing to do here.
23129             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23130                 continue;
23131             }
23132             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23133                 continue;
23134             }
23135             // If process state is not changed, then there's nothing to do.
23136             if (uidRec.setProcState == uidRec.curProcState) {
23137                 continue;
23138             }
23139             final int blockState = getBlockStateForUid(uidRec);
23140             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23141             // there's nothing the app needs to do in this scenario.
23142             if (blockState == NETWORK_STATE_NO_CHANGE) {
23143                 continue;
23144             }
23145             synchronized (uidRec.networkStateLock) {
23146                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23147                 if (blockState == NETWORK_STATE_BLOCK) {
23148                     if (blockingUids == null) {
23149                         blockingUids = new ArrayList<>();
23150                     }
23151                     blockingUids.add(uidRec.uid);
23152                 } else {
23153                     if (DEBUG_NETWORK) {
23154                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23155                                 + " threads for uid: " + uidRec);
23156                     }
23157                     if (uidRec.waitingForNetwork) {
23158                         uidRec.networkStateLock.notifyAll();
23159                     }
23160                 }
23161             }
23162         }
23163
23164         // There are no uids that need to block, so nothing more to do.
23165         if (blockingUids == null) {
23166             return;
23167         }
23168
23169         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23170             final ProcessRecord app = mLruProcesses.get(i);
23171             if (!blockingUids.contains(app.uid)) {
23172                 continue;
23173             }
23174             if (!app.killedByAm && app.thread != null) {
23175                 final UidRecord uidRec = mActiveUids.get(app.uid);
23176                 try {
23177                     if (DEBUG_NETWORK) {
23178                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23179                                 + uidRec);
23180                     }
23181                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23182                 } catch (RemoteException ignored) {
23183                 }
23184             }
23185         }
23186     }
23187
23188     /**
23189      * Checks if the uid is coming from background to foreground or vice versa and returns
23190      * appropriate block state based on this.
23191      *
23192      * @return blockState based on whether the uid is coming from background to foreground or
23193      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23194      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23195      *         {@link #NETWORK_STATE_NO_CHANGE}.
23196      */
23197     @VisibleForTesting
23198     int getBlockStateForUid(UidRecord uidRec) {
23199         // Denotes whether uid's process state is currently allowed network access.
23200         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23201                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23202         // Denotes whether uid's process state was previously allowed network access.
23203         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23204                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23205
23206         // When the uid is coming to foreground, AMS should inform the app thread that it should
23207         // block for the network rules to get updated before launching an activity.
23208         if (!wasAllowed && isAllowed) {
23209             return NETWORK_STATE_BLOCK;
23210         }
23211         // When the uid is going to background, AMS should inform the app thread that if an
23212         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23213         if (wasAllowed && !isAllowed) {
23214             return NETWORK_STATE_UNBLOCK;
23215         }
23216         return NETWORK_STATE_NO_CHANGE;
23217     }
23218
23219     final void runInBackgroundDisabled(int uid) {
23220         synchronized (this) {
23221             UidRecord uidRec = mActiveUids.get(uid);
23222             if (uidRec != null) {
23223                 // This uid is actually running...  should it be considered background now?
23224                 if (uidRec.idle) {
23225                     doStopUidLocked(uidRec.uid, uidRec);
23226                 }
23227             } else {
23228                 // This uid isn't actually running...  still send a report about it being "stopped".
23229                 doStopUidLocked(uid, null);
23230             }
23231         }
23232     }
23233
23234     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23235         mServices.stopInBackgroundLocked(uid);
23236         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23237     }
23238
23239     /**
23240      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23241      */
23242     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23243             long duration, String tag) {
23244         if (DEBUG_WHITELISTS) {
23245             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23246                     + targetUid + ", " + duration + ")");
23247         }
23248
23249         synchronized (mPidsSelfLocked) {
23250             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23251             if (pr == null) {
23252                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23253                         + callerPid);
23254                 return;
23255             }
23256             if (!pr.whitelistManager) {
23257                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23258                         != PackageManager.PERMISSION_GRANTED) {
23259                     if (DEBUG_WHITELISTS) {
23260                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23261                                 + ": pid " + callerPid + " is not allowed");
23262                     }
23263                     return;
23264                 }
23265             }
23266         }
23267
23268         tempWhitelistUidLocked(targetUid, duration, tag);
23269     }
23270
23271     /**
23272      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23273      */
23274     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23275         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23276         setUidTempWhitelistStateLocked(targetUid, true);
23277         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23278     }
23279
23280     void pushTempWhitelist() {
23281         final int N;
23282         final PendingTempWhitelist[] list;
23283
23284         // First copy out the pending changes...  we need to leave them in the map for now,
23285         // in case someone needs to check what is coming up while we don't have the lock held.
23286         synchronized(this) {
23287             N = mPendingTempWhitelist.size();
23288             list = new PendingTempWhitelist[N];
23289             for (int i = 0; i < N; i++) {
23290                 list[i] = mPendingTempWhitelist.valueAt(i);
23291             }
23292         }
23293
23294         // Now safely dispatch changes to device idle controller.
23295         for (int i = 0; i < N; i++) {
23296             PendingTempWhitelist ptw = list[i];
23297             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23298                     ptw.duration, true, ptw.tag);
23299         }
23300
23301         // And now we can safely remove them from the map.
23302         synchronized(this) {
23303             for (int i = 0; i < N; i++) {
23304                 PendingTempWhitelist ptw = list[i];
23305                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23306                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23307                     mPendingTempWhitelist.removeAt(index);
23308                 }
23309             }
23310         }
23311     }
23312
23313     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23314         boolean changed = false;
23315         for (int i=mActiveUids.size()-1; i>=0; i--) {
23316             final UidRecord uidRec = mActiveUids.valueAt(i);
23317             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23318                 uidRec.curWhitelist = onWhitelist;
23319                 changed = true;
23320             }
23321         }
23322         if (changed) {
23323             updateOomAdjLocked();
23324         }
23325     }
23326
23327     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23328         boolean changed = false;
23329         final UidRecord uidRec = mActiveUids.get(uid);
23330         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23331             uidRec.curWhitelist = onWhitelist;
23332             updateOomAdjLocked();
23333         }
23334     }
23335
23336     final void trimApplications() {
23337         synchronized (this) {
23338             int i;
23339
23340             // First remove any unused application processes whose package
23341             // has been removed.
23342             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23343                 final ProcessRecord app = mRemovedProcesses.get(i);
23344                 if (app.activities.size() == 0
23345                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23346                     Slog.i(
23347                         TAG, "Exiting empty application process "
23348                         + app.toShortString() + " ("
23349                         + (app.thread != null ? app.thread.asBinder() : null)
23350                         + ")\n");
23351                     if (app.pid > 0 && app.pid != MY_PID) {
23352                         app.kill("empty", false);
23353                     } else {
23354                         try {
23355                             app.thread.scheduleExit();
23356                         } catch (Exception e) {
23357                             // Ignore exceptions.
23358                         }
23359                     }
23360                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23361                     mRemovedProcesses.remove(i);
23362
23363                     if (app.persistent) {
23364                         addAppLocked(app.info, null, false, null /* ABI override */);
23365                     }
23366                 }
23367             }
23368
23369             // Now update the oom adj for all processes.
23370             updateOomAdjLocked();
23371         }
23372     }
23373
23374     /** This method sends the specified signal to each of the persistent apps */
23375     public void signalPersistentProcesses(int sig) throws RemoteException {
23376         if (sig != SIGNAL_USR1) {
23377             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23378         }
23379
23380         synchronized (this) {
23381             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23382                     != PackageManager.PERMISSION_GRANTED) {
23383                 throw new SecurityException("Requires permission "
23384                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23385             }
23386
23387             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23388                 ProcessRecord r = mLruProcesses.get(i);
23389                 if (r.thread != null && r.persistent) {
23390                     sendSignal(r.pid, sig);
23391                 }
23392             }
23393         }
23394     }
23395
23396     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23397         if (proc == null || proc == mProfileProc) {
23398             proc = mProfileProc;
23399             profileType = mProfileType;
23400             clearProfilerLocked();
23401         }
23402         if (proc == null) {
23403             return;
23404         }
23405         try {
23406             proc.thread.profilerControl(false, null, profileType);
23407         } catch (RemoteException e) {
23408             throw new IllegalStateException("Process disappeared");
23409         }
23410     }
23411
23412     private void clearProfilerLocked() {
23413         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23414             try {
23415                 mProfilerInfo.profileFd.close();
23416             } catch (IOException e) {
23417             }
23418         }
23419         mProfileApp = null;
23420         mProfileProc = null;
23421         mProfilerInfo = null;
23422     }
23423
23424     public boolean profileControl(String process, int userId, boolean start,
23425             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23426
23427         try {
23428             synchronized (this) {
23429                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23430                 // its own permission.
23431                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23432                         != PackageManager.PERMISSION_GRANTED) {
23433                     throw new SecurityException("Requires permission "
23434                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23435                 }
23436
23437                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23438                     throw new IllegalArgumentException("null profile info or fd");
23439                 }
23440
23441                 ProcessRecord proc = null;
23442                 if (process != null) {
23443                     proc = findProcessLocked(process, userId, "profileControl");
23444                 }
23445
23446                 if (start && (proc == null || proc.thread == null)) {
23447                     throw new IllegalArgumentException("Unknown process: " + process);
23448                 }
23449
23450                 if (start) {
23451                     stopProfilerLocked(null, 0);
23452                     setProfileApp(proc.info, proc.processName, profilerInfo);
23453                     mProfileProc = proc;
23454                     mProfileType = profileType;
23455                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23456                     try {
23457                         fd = fd.dup();
23458                     } catch (IOException e) {
23459                         fd = null;
23460                     }
23461                     profilerInfo.profileFd = fd;
23462                     proc.thread.profilerControl(start, profilerInfo, profileType);
23463                     fd = null;
23464                     try {
23465                         mProfilerInfo.profileFd.close();
23466                     } catch (IOException e) {
23467                     }
23468                     mProfilerInfo.profileFd = null;
23469                 } else {
23470                     stopProfilerLocked(proc, profileType);
23471                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23472                         try {
23473                             profilerInfo.profileFd.close();
23474                         } catch (IOException e) {
23475                         }
23476                     }
23477                 }
23478
23479                 return true;
23480             }
23481         } catch (RemoteException e) {
23482             throw new IllegalStateException("Process disappeared");
23483         } finally {
23484             if (profilerInfo != null && profilerInfo.profileFd != null) {
23485                 try {
23486                     profilerInfo.profileFd.close();
23487                 } catch (IOException e) {
23488                 }
23489             }
23490         }
23491     }
23492
23493     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23494         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23495                 userId, true, ALLOW_FULL_ONLY, callName, null);
23496         ProcessRecord proc = null;
23497         try {
23498             int pid = Integer.parseInt(process);
23499             synchronized (mPidsSelfLocked) {
23500                 proc = mPidsSelfLocked.get(pid);
23501             }
23502         } catch (NumberFormatException e) {
23503         }
23504
23505         if (proc == null) {
23506             ArrayMap<String, SparseArray<ProcessRecord>> all
23507                     = mProcessNames.getMap();
23508             SparseArray<ProcessRecord> procs = all.get(process);
23509             if (procs != null && procs.size() > 0) {
23510                 proc = procs.valueAt(0);
23511                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23512                     for (int i=1; i<procs.size(); i++) {
23513                         ProcessRecord thisProc = procs.valueAt(i);
23514                         if (thisProc.userId == userId) {
23515                             proc = thisProc;
23516                             break;
23517                         }
23518                     }
23519                 }
23520             }
23521         }
23522
23523         return proc;
23524     }
23525
23526     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23527             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23528
23529         try {
23530             synchronized (this) {
23531                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23532                 // its own permission (same as profileControl).
23533                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23534                         != PackageManager.PERMISSION_GRANTED) {
23535                     throw new SecurityException("Requires permission "
23536                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23537                 }
23538
23539                 if (fd == null) {
23540                     throw new IllegalArgumentException("null fd");
23541                 }
23542
23543                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23544                 if (proc == null || proc.thread == null) {
23545                     throw new IllegalArgumentException("Unknown process: " + process);
23546                 }
23547
23548                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23549                 if (!isDebuggable) {
23550                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23551                         throw new SecurityException("Process not debuggable: " + proc);
23552                     }
23553                 }
23554
23555                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23556                 fd = null;
23557                 return true;
23558             }
23559         } catch (RemoteException e) {
23560             throw new IllegalStateException("Process disappeared");
23561         } finally {
23562             if (fd != null) {
23563                 try {
23564                     fd.close();
23565                 } catch (IOException e) {
23566                 }
23567             }
23568         }
23569     }
23570
23571     @Override
23572     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23573             String reportPackage) {
23574         if (processName != null) {
23575             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23576                     "setDumpHeapDebugLimit()");
23577         } else {
23578             synchronized (mPidsSelfLocked) {
23579                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23580                 if (proc == null) {
23581                     throw new SecurityException("No process found for calling pid "
23582                             + Binder.getCallingPid());
23583                 }
23584                 if (!Build.IS_DEBUGGABLE
23585                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23586                     throw new SecurityException("Not running a debuggable build");
23587                 }
23588                 processName = proc.processName;
23589                 uid = proc.uid;
23590                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23591                     throw new SecurityException("Package " + reportPackage + " is not running in "
23592                             + proc);
23593                 }
23594             }
23595         }
23596         synchronized (this) {
23597             if (maxMemSize > 0) {
23598                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23599             } else {
23600                 if (uid != 0) {
23601                     mMemWatchProcesses.remove(processName, uid);
23602                 } else {
23603                     mMemWatchProcesses.getMap().remove(processName);
23604                 }
23605             }
23606         }
23607     }
23608
23609     @Override
23610     public void dumpHeapFinished(String path) {
23611         synchronized (this) {
23612             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23613                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23614                         + " does not match last pid " + mMemWatchDumpPid);
23615                 return;
23616             }
23617             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23618                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23619                         + " does not match last path " + mMemWatchDumpFile);
23620                 return;
23621             }
23622             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23623             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23624
23625             // Forced gc to clean up the remnant hprof fd.
23626             Runtime.getRuntime().gc();
23627         }
23628     }
23629
23630     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23631     public void monitor() {
23632         synchronized (this) { }
23633     }
23634
23635     void onCoreSettingsChange(Bundle settings) {
23636         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23637             ProcessRecord processRecord = mLruProcesses.get(i);
23638             try {
23639                 if (processRecord.thread != null) {
23640                     processRecord.thread.setCoreSettings(settings);
23641                 }
23642             } catch (RemoteException re) {
23643                 /* ignore */
23644             }
23645         }
23646     }
23647
23648     // Multi-user methods
23649
23650     /**
23651      * Start user, if its not already running, but don't bring it to foreground.
23652      */
23653     @Override
23654     public boolean startUserInBackground(final int userId) {
23655         return mUserController.startUser(userId, /* foreground */ false);
23656     }
23657
23658     @Override
23659     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23660         return mUserController.unlockUser(userId, token, secret, listener);
23661     }
23662
23663     @Override
23664     public boolean switchUser(final int targetUserId) {
23665         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23666         int currentUserId;
23667         UserInfo targetUserInfo;
23668         synchronized (this) {
23669             currentUserId = mUserController.getCurrentUserIdLocked();
23670             targetUserInfo = mUserController.getUserInfo(targetUserId);
23671             if (targetUserId == currentUserId) {
23672                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23673                 return true;
23674             }
23675             if (targetUserInfo == null) {
23676                 Slog.w(TAG, "No user info for user #" + targetUserId);
23677                 return false;
23678             }
23679             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23680                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23681                         + " when device is in demo mode");
23682                 return false;
23683             }
23684             if (!targetUserInfo.supportsSwitchTo()) {
23685                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23686                 return false;
23687             }
23688             if (targetUserInfo.isManagedProfile()) {
23689                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23690                 return false;
23691             }
23692             mUserController.setTargetUserIdLocked(targetUserId);
23693         }
23694         if (mUserController.mUserSwitchUiEnabled) {
23695             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23696             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23697             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23698             mUiHandler.sendMessage(mHandler.obtainMessage(
23699                     START_USER_SWITCH_UI_MSG, userNames));
23700         } else {
23701             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23702             mHandler.sendMessage(mHandler.obtainMessage(
23703                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23704         }
23705         return true;
23706     }
23707
23708     void scheduleStartProfilesLocked() {
23709         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23710             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23711                     DateUtils.SECOND_IN_MILLIS);
23712         }
23713     }
23714
23715     @Override
23716     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23717         return mUserController.stopUser(userId, force, callback);
23718     }
23719
23720     @Override
23721     public UserInfo getCurrentUser() {
23722         return mUserController.getCurrentUser();
23723     }
23724
23725     String getStartedUserState(int userId) {
23726         synchronized (this) {
23727             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23728             return UserState.stateToString(userState.state);
23729         }
23730     }
23731
23732     @Override
23733     public boolean isUserRunning(int userId, int flags) {
23734         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23735                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23736                     != PackageManager.PERMISSION_GRANTED) {
23737             String msg = "Permission Denial: isUserRunning() from pid="
23738                     + Binder.getCallingPid()
23739                     + ", uid=" + Binder.getCallingUid()
23740                     + " requires " + INTERACT_ACROSS_USERS;
23741             Slog.w(TAG, msg);
23742             throw new SecurityException(msg);
23743         }
23744         synchronized (this) {
23745             return mUserController.isUserRunningLocked(userId, flags);
23746         }
23747     }
23748
23749     @Override
23750     public int[] getRunningUserIds() {
23751         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23752                 != PackageManager.PERMISSION_GRANTED) {
23753             String msg = "Permission Denial: isUserRunning() from pid="
23754                     + Binder.getCallingPid()
23755                     + ", uid=" + Binder.getCallingUid()
23756                     + " requires " + INTERACT_ACROSS_USERS;
23757             Slog.w(TAG, msg);
23758             throw new SecurityException(msg);
23759         }
23760         synchronized (this) {
23761             return mUserController.getStartedUserArrayLocked();
23762         }
23763     }
23764
23765     @Override
23766     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23767         mUserController.registerUserSwitchObserver(observer, name);
23768     }
23769
23770     @Override
23771     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23772         mUserController.unregisterUserSwitchObserver(observer);
23773     }
23774
23775     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23776         if (info == null) return null;
23777         ApplicationInfo newInfo = new ApplicationInfo(info);
23778         newInfo.initForUser(userId);
23779         return newInfo;
23780     }
23781
23782     public boolean isUserStopped(int userId) {
23783         synchronized (this) {
23784             return mUserController.getStartedUserStateLocked(userId) == null;
23785         }
23786     }
23787
23788     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23789         if (aInfo == null
23790                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23791             return aInfo;
23792         }
23793
23794         ActivityInfo info = new ActivityInfo(aInfo);
23795         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23796         return info;
23797     }
23798
23799     private boolean processSanityChecksLocked(ProcessRecord process) {
23800         if (process == null || process.thread == null) {
23801             return false;
23802         }
23803
23804         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23805         if (!isDebuggable) {
23806             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23807                 return false;
23808             }
23809         }
23810
23811         return true;
23812     }
23813
23814     public boolean startBinderTracking() throws RemoteException {
23815         synchronized (this) {
23816             mBinderTransactionTrackingEnabled = true;
23817             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23818             // permission (same as profileControl).
23819             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23820                     != PackageManager.PERMISSION_GRANTED) {
23821                 throw new SecurityException("Requires permission "
23822                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23823             }
23824
23825             for (int i = 0; i < mLruProcesses.size(); i++) {
23826                 ProcessRecord process = mLruProcesses.get(i);
23827                 if (!processSanityChecksLocked(process)) {
23828                     continue;
23829                 }
23830                 try {
23831                     process.thread.startBinderTracking();
23832                 } catch (RemoteException e) {
23833                     Log.v(TAG, "Process disappared");
23834                 }
23835             }
23836             return true;
23837         }
23838     }
23839
23840     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23841         try {
23842             synchronized (this) {
23843                 mBinderTransactionTrackingEnabled = false;
23844                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23845                 // permission (same as profileControl).
23846                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23847                         != PackageManager.PERMISSION_GRANTED) {
23848                     throw new SecurityException("Requires permission "
23849                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23850                 }
23851
23852                 if (fd == null) {
23853                     throw new IllegalArgumentException("null fd");
23854                 }
23855
23856                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23857                 pw.println("Binder transaction traces for all processes.\n");
23858                 for (ProcessRecord process : mLruProcesses) {
23859                     if (!processSanityChecksLocked(process)) {
23860                         continue;
23861                     }
23862
23863                     pw.println("Traces for process: " + process.processName);
23864                     pw.flush();
23865                     try {
23866                         TransferPipe tp = new TransferPipe();
23867                         try {
23868                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23869                             tp.go(fd.getFileDescriptor());
23870                         } finally {
23871                             tp.kill();
23872                         }
23873                     } catch (IOException e) {
23874                         pw.println("Failure while dumping IPC traces from " + process +
23875                                 ".  Exception: " + e);
23876                         pw.flush();
23877                     } catch (RemoteException e) {
23878                         pw.println("Got a RemoteException while dumping IPC traces from " +
23879                                 process + ".  Exception: " + e);
23880                         pw.flush();
23881                     }
23882                 }
23883                 fd = null;
23884                 return true;
23885             }
23886         } finally {
23887             if (fd != null) {
23888                 try {
23889                     fd.close();
23890                 } catch (IOException e) {
23891                 }
23892             }
23893         }
23894     }
23895
23896     @VisibleForTesting
23897     final class LocalService extends ActivityManagerInternal {
23898         @Override
23899         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23900                 int targetUserId) {
23901             synchronized (ActivityManagerService.this) {
23902                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23903                         targetPkg, intent, null, targetUserId);
23904             }
23905         }
23906
23907         @Override
23908         public String checkContentProviderAccess(String authority, int userId) {
23909             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23910         }
23911
23912         @Override
23913         public void onWakefulnessChanged(int wakefulness) {
23914             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23915         }
23916
23917         @Override
23918         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23919                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23920             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23921                     processName, abiOverride, uid, crashHandler);
23922         }
23923
23924         @Override
23925         public SleepToken acquireSleepToken(String tag, int displayId) {
23926             Preconditions.checkNotNull(tag);
23927             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23928         }
23929
23930         @Override
23931         public ComponentName getHomeActivityForUser(int userId) {
23932             synchronized (ActivityManagerService.this) {
23933                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23934                 return homeActivity == null ? null : homeActivity.realActivity;
23935             }
23936         }
23937
23938         @Override
23939         public void onUserRemoved(int userId) {
23940             synchronized (ActivityManagerService.this) {
23941                 ActivityManagerService.this.onUserStoppedLocked(userId);
23942             }
23943             mBatteryStatsService.onUserRemoved(userId);
23944         }
23945
23946         @Override
23947         public void onLocalVoiceInteractionStarted(IBinder activity,
23948                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23949             synchronized (ActivityManagerService.this) {
23950                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23951                         voiceSession, voiceInteractor);
23952             }
23953         }
23954
23955         @Override
23956         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23957             synchronized (ActivityManagerService.this) {
23958                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23959                         reasons, timestamp);
23960             }
23961         }
23962
23963         @Override
23964         public void notifyAppTransitionFinished() {
23965             synchronized (ActivityManagerService.this) {
23966                 mStackSupervisor.notifyAppTransitionDone();
23967             }
23968         }
23969
23970         @Override
23971         public void notifyAppTransitionCancelled() {
23972             synchronized (ActivityManagerService.this) {
23973                 mStackSupervisor.notifyAppTransitionDone();
23974             }
23975         }
23976
23977         @Override
23978         public List<IBinder> getTopVisibleActivities() {
23979             synchronized (ActivityManagerService.this) {
23980                 return mStackSupervisor.getTopVisibleActivities();
23981             }
23982         }
23983
23984         @Override
23985         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23986             synchronized (ActivityManagerService.this) {
23987                 mStackSupervisor.setDockedStackMinimized(minimized);
23988             }
23989         }
23990
23991         @Override
23992         public void killForegroundAppsForUser(int userHandle) {
23993             synchronized (ActivityManagerService.this) {
23994                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23995                 final int NP = mProcessNames.getMap().size();
23996                 for (int ip = 0; ip < NP; ip++) {
23997                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
23998                     final int NA = apps.size();
23999                     for (int ia = 0; ia < NA; ia++) {
24000                         final ProcessRecord app = apps.valueAt(ia);
24001                         if (app.persistent) {
24002                             // We don't kill persistent processes.
24003                             continue;
24004                         }
24005                         if (app.removed) {
24006                             procs.add(app);
24007                         } else if (app.userId == userHandle && app.foregroundActivities) {
24008                             app.removed = true;
24009                             procs.add(app);
24010                         }
24011                     }
24012                 }
24013
24014                 final int N = procs.size();
24015                 for (int i = 0; i < N; i++) {
24016                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
24017                 }
24018             }
24019         }
24020
24021         @Override
24022         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24023                 long duration) {
24024             if (!(target instanceof PendingIntentRecord)) {
24025                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24026                 return;
24027             }
24028             synchronized (ActivityManagerService.this) {
24029                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24030             }
24031         }
24032
24033         @Override
24034         public void setDeviceIdleWhitelist(int[] appids) {
24035             synchronized (ActivityManagerService.this) {
24036                 mDeviceIdleWhitelist = appids;
24037             }
24038         }
24039
24040         @Override
24041         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24042             synchronized (ActivityManagerService.this) {
24043                 mDeviceIdleTempWhitelist = appids;
24044                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24045             }
24046         }
24047
24048         @Override
24049         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24050                 int userId) {
24051             Preconditions.checkNotNull(values, "Configuration must not be null");
24052             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24053             synchronized (ActivityManagerService.this) {
24054                 updateConfigurationLocked(values, null, false, true, userId,
24055                         false /* deferResume */);
24056             }
24057         }
24058
24059         @Override
24060         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24061                 Bundle bOptions) {
24062             Preconditions.checkNotNull(intents, "intents");
24063             final String[] resolvedTypes = new String[intents.length];
24064             for (int i = 0; i < intents.length; i++) {
24065                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24066             }
24067
24068             // UID of the package on user userId.
24069             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24070             // packageUid may not be initialized.
24071             int packageUid = 0;
24072             try {
24073                 packageUid = AppGlobals.getPackageManager().getPackageUid(
24074                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24075             } catch (RemoteException e) {
24076                 // Shouldn't happen.
24077             }
24078
24079             synchronized (ActivityManagerService.this) {
24080                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24081                         /*resultTo*/ null, bOptions, userId);
24082             }
24083         }
24084
24085         @Override
24086         public int getUidProcessState(int uid) {
24087             return getUidState(uid);
24088         }
24089
24090         @Override
24091         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24092             synchronized (ActivityManagerService.this) {
24093
24094                 // We might change the visibilities here, so prepare an empty app transition which
24095                 // might be overridden later if we actually change visibilities.
24096                 final boolean wasTransitionSet =
24097                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24098                 if (!wasTransitionSet) {
24099                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24100                             false /* alwaysKeepCurrent */);
24101                 }
24102                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24103
24104                 // If there was a transition set already we don't want to interfere with it as we
24105                 // might be starting it too early.
24106                 if (!wasTransitionSet) {
24107                     mWindowManager.executeAppTransition();
24108                 }
24109             }
24110             if (callback != null) {
24111                 callback.run();
24112             }
24113         }
24114
24115         @Override
24116         public boolean isSystemReady() {
24117             // no need to synchronize(this) just to read & return the value
24118             return mSystemReady;
24119         }
24120
24121         @Override
24122         public void notifyKeyguardTrustedChanged() {
24123             synchronized (ActivityManagerService.this) {
24124                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24125                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24126                 }
24127             }
24128         }
24129
24130         /**
24131          * Sets if the given pid has an overlay UI or not.
24132          *
24133          * @param pid The pid we are setting overlay UI for.
24134          * @param hasOverlayUi True if the process has overlay UI.
24135          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24136          */
24137         @Override
24138         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24139             synchronized (ActivityManagerService.this) {
24140                 final ProcessRecord pr;
24141                 synchronized (mPidsSelfLocked) {
24142                     pr = mPidsSelfLocked.get(pid);
24143                     if (pr == null) {
24144                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24145                         return;
24146                     }
24147                 }
24148                 if (pr.hasOverlayUi == hasOverlayUi) {
24149                     return;
24150                 }
24151                 pr.hasOverlayUi = hasOverlayUi;
24152                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24153                 updateOomAdjLocked(pr, true);
24154             }
24155         }
24156
24157         /**
24158          * Called after the network policy rules are updated by
24159          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24160          * and {@param procStateSeq}.
24161          */
24162         @Override
24163         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24164             if (DEBUG_NETWORK) {
24165                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24166                         + uid + " seq: " + procStateSeq);
24167             }
24168             UidRecord record;
24169             synchronized (ActivityManagerService.this) {
24170                 record = mActiveUids.get(uid);
24171                 if (record == null) {
24172                     if (DEBUG_NETWORK) {
24173                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24174                                 + " procStateSeq: " + procStateSeq);
24175                     }
24176                     return;
24177                 }
24178             }
24179             synchronized (record.networkStateLock) {
24180                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24181                     if (DEBUG_NETWORK) {
24182                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24183                                 + " been handled for uid: " + uid);
24184                     }
24185                     return;
24186                 }
24187                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24188                 if (record.curProcStateSeq > procStateSeq) {
24189                     if (DEBUG_NETWORK) {
24190                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24191                                 + ", curProcstateSeq: " + record.curProcStateSeq
24192                                 + ", procStateSeq: " + procStateSeq);
24193                     }
24194                     return;
24195                 }
24196                 if (record.waitingForNetwork) {
24197                     if (DEBUG_NETWORK) {
24198                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24199                                 + ", procStateSeq: " + procStateSeq);
24200                     }
24201                     record.networkStateLock.notifyAll();
24202                 }
24203             }
24204         }
24205
24206         /**
24207          * Called after virtual display Id is updated by
24208          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24209          * {@param vrVr2dDisplayId}.
24210          */
24211         @Override
24212         public void setVr2dDisplayId(int vr2dDisplayId) {
24213             if (DEBUG_STACK) {
24214                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24215                         vr2dDisplayId);
24216             }
24217             synchronized (ActivityManagerService.this) {
24218                 mVr2dDisplayId = vr2dDisplayId;
24219             }
24220         }
24221
24222         @Override
24223         public void saveANRState(String reason) {
24224             synchronized (ActivityManagerService.this) {
24225                 final StringWriter sw = new StringWriter();
24226                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24227                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24228                 if (reason != null) {
24229                     pw.println("  Reason: " + reason);
24230                 }
24231                 pw.println();
24232                 mActivityStarter.dump(pw, "  ", null);
24233                 pw.println();
24234                 pw.println("-------------------------------------------------------------------------------");
24235                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24236                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24237                         "" /* header */);
24238                 pw.println();
24239                 pw.close();
24240
24241                 mLastANRState = sw.toString();
24242             }
24243         }
24244
24245         @Override
24246         public void clearSavedANRState() {
24247             synchronized (ActivityManagerService.this) {
24248                 mLastANRState = null;
24249             }
24250         }
24251
24252         @Override
24253         public void setFocusedActivity(IBinder token) {
24254             synchronized (ActivityManagerService.this) {
24255                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24256                 if (r == null) {
24257                     throw new IllegalArgumentException(
24258                             "setFocusedActivity: No activity record matching token=" + token);
24259                 }
24260                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24261                         r, "setFocusedActivity")) {
24262                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
24263                 }
24264             }
24265         }
24266
24267         @Override
24268         public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24269             if (packageName == null) return false;
24270
24271             synchronized (ActivityManagerService.this) {
24272                 for (int i = 0; i < mLruProcesses.size(); i++) {
24273                     final ProcessRecord processRecord = mLruProcesses.get(i);
24274                     if (processRecord.uid == uid) {
24275                         for (int j = 0; j < processRecord.activities.size(); j++) {
24276                             final ActivityRecord activityRecord = processRecord.activities.get(j);
24277                             if (packageName.equals(activityRecord.packageName)) {
24278                                 return true;
24279                             }
24280                         }
24281                     }
24282                 }
24283             }
24284             return false;
24285         }
24286     }
24287
24288     /**
24289      * Called by app main thread to wait for the network policy rules to get updated.
24290      *
24291      * @param procStateSeq The sequence number indicating the process state change that the main
24292      *                     thread is interested in.
24293      */
24294     @Override
24295     public void waitForNetworkStateUpdate(long procStateSeq) {
24296         final int callingUid = Binder.getCallingUid();
24297         if (DEBUG_NETWORK) {
24298             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24299         }
24300         UidRecord record;
24301         synchronized (this) {
24302             record = mActiveUids.get(callingUid);
24303             if (record == null) {
24304                 return;
24305             }
24306         }
24307         synchronized (record.networkStateLock) {
24308             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24309                 if (DEBUG_NETWORK) {
24310                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24311                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24312                             + " lastProcStateSeqDispatchedToObservers: "
24313                             + record.lastDispatchedProcStateSeq);
24314                 }
24315                 return;
24316             }
24317             if (record.curProcStateSeq > procStateSeq) {
24318                 if (DEBUG_NETWORK) {
24319                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24320                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24321                             + ", procStateSeq: " + procStateSeq);
24322                 }
24323                 return;
24324             }
24325             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24326                 if (DEBUG_NETWORK) {
24327                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24328                             + procStateSeq + ", so no need to wait. Uid: "
24329                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24330                             + record.lastNetworkUpdatedProcStateSeq);
24331                 }
24332                 return;
24333             }
24334             try {
24335                 if (DEBUG_NETWORK) {
24336                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24337                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24338                 }
24339                 final long startTime = SystemClock.uptimeMillis();
24340                 record.waitingForNetwork = true;
24341                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24342                 record.waitingForNetwork = false;
24343                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24344                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24345                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24346                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24347                             + procStateSeq + " UidRec: " + record
24348                             + " validateUidRec: " + mValidateUids.get(callingUid));
24349                 }
24350             } catch (InterruptedException e) {
24351                 Thread.currentThread().interrupt();
24352             }
24353         }
24354     }
24355
24356     public void waitForBroadcastIdle(PrintWriter pw) {
24357         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24358         while (true) {
24359             boolean idle = true;
24360             synchronized (this) {
24361                 for (BroadcastQueue queue : mBroadcastQueues) {
24362                     if (!queue.isIdle()) {
24363                         final String msg = "Waiting for queue " + queue + " to become idle...";
24364                         pw.println(msg);
24365                         pw.flush();
24366                         Slog.v(TAG, msg);
24367                         idle = false;
24368                     }
24369                 }
24370             }
24371
24372             if (idle) {
24373                 final String msg = "All broadcast queues are idle!";
24374                 pw.println(msg);
24375                 pw.flush();
24376                 Slog.v(TAG, msg);
24377                 return;
24378             } else {
24379                 SystemClock.sleep(1000);
24380             }
24381         }
24382     }
24383
24384     /**
24385      * Return the user id of the last resumed activity.
24386      */
24387     @Override
24388     public @UserIdInt int getLastResumedActivityUserId() {
24389         enforceCallingPermission(
24390                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24391         synchronized (this) {
24392             if (mLastResumedActivity == null) {
24393                 return mUserController.getCurrentUserIdLocked();
24394             }
24395             return mLastResumedActivity.userId;
24396         }
24397     }
24398
24399     /**
24400      * An implementation of IAppTask, that allows an app to manage its own tasks via
24401      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24402      * only the process that calls getAppTasks() can call the AppTask methods.
24403      */
24404     class AppTaskImpl extends IAppTask.Stub {
24405         private int mTaskId;
24406         private int mCallingUid;
24407
24408         public AppTaskImpl(int taskId, int callingUid) {
24409             mTaskId = taskId;
24410             mCallingUid = callingUid;
24411         }
24412
24413         private void checkCaller() {
24414             if (mCallingUid != Binder.getCallingUid()) {
24415                 throw new SecurityException("Caller " + mCallingUid
24416                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24417             }
24418         }
24419
24420         @Override
24421         public void finishAndRemoveTask() {
24422             checkCaller();
24423
24424             synchronized (ActivityManagerService.this) {
24425                 long origId = Binder.clearCallingIdentity();
24426                 try {
24427                     // We remove the task from recents to preserve backwards
24428                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24429                             REMOVE_FROM_RECENTS)) {
24430                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24431                     }
24432                 } finally {
24433                     Binder.restoreCallingIdentity(origId);
24434                 }
24435             }
24436         }
24437
24438         @Override
24439         public ActivityManager.RecentTaskInfo getTaskInfo() {
24440             checkCaller();
24441
24442             synchronized (ActivityManagerService.this) {
24443                 long origId = Binder.clearCallingIdentity();
24444                 try {
24445                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24446                     if (tr == null) {
24447                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24448                     }
24449                     return createRecentTaskInfoFromTaskRecord(tr);
24450                 } finally {
24451                     Binder.restoreCallingIdentity(origId);
24452                 }
24453             }
24454         }
24455
24456         @Override
24457         public void moveToFront() {
24458             checkCaller();
24459             // Will bring task to front if it already has a root activity.
24460             final long origId = Binder.clearCallingIdentity();
24461             try {
24462                 synchronized (this) {
24463                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24464                 }
24465             } finally {
24466                 Binder.restoreCallingIdentity(origId);
24467             }
24468         }
24469
24470         @Override
24471         public int startActivity(IBinder whoThread, String callingPackage,
24472                 Intent intent, String resolvedType, Bundle bOptions) {
24473             checkCaller();
24474
24475             int callingUser = UserHandle.getCallingUserId();
24476             TaskRecord tr;
24477             IApplicationThread appThread;
24478             synchronized (ActivityManagerService.this) {
24479                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24480                 if (tr == null) {
24481                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24482                 }
24483                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24484                 if (appThread == null) {
24485                     throw new IllegalArgumentException("Bad app thread " + appThread);
24486                 }
24487             }
24488             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24489                     resolvedType, null, null, null, null, 0, 0, null, null,
24490                     null, bOptions, false, callingUser, tr, "AppTaskImpl");
24491         }
24492
24493         @Override
24494         public void setExcludeFromRecents(boolean exclude) {
24495             checkCaller();
24496
24497             synchronized (ActivityManagerService.this) {
24498                 long origId = Binder.clearCallingIdentity();
24499                 try {
24500                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24501                     if (tr == null) {
24502                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24503                     }
24504                     Intent intent = tr.getBaseIntent();
24505                     if (exclude) {
24506                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24507                     } else {
24508                         intent.setFlags(intent.getFlags()
24509                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24510                     }
24511                 } finally {
24512                     Binder.restoreCallingIdentity(origId);
24513                 }
24514             }
24515         }
24516     }
24517
24518     /**
24519      * Kill processes for the user with id userId and that depend on the package named packageName
24520      */
24521     @Override
24522     public void killPackageDependents(String packageName, int userId) {
24523         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24524         if (packageName == null) {
24525             throw new NullPointerException(
24526                     "Cannot kill the dependents of a package without its name.");
24527         }
24528
24529         long callingId = Binder.clearCallingIdentity();
24530         IPackageManager pm = AppGlobals.getPackageManager();
24531         int pkgUid = -1;
24532         try {
24533             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24534         } catch (RemoteException e) {
24535         }
24536         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24537             throw new IllegalArgumentException(
24538                     "Cannot kill dependents of non-existing package " + packageName);
24539         }
24540         try {
24541             synchronized(this) {
24542                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24543                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24544                         "dep: " + packageName);
24545             }
24546         } finally {
24547             Binder.restoreCallingIdentity(callingId);
24548         }
24549     }
24550
24551     @Override
24552     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24553             throws RemoteException {
24554         final long callingId = Binder.clearCallingIdentity();
24555         try {
24556             mKeyguardController.dismissKeyguard(token, callback);
24557         } finally {
24558             Binder.restoreCallingIdentity(callingId);
24559         }
24560     }
24561
24562     @Override
24563     public int restartUserInBackground(final int userId) {
24564         return mUserController.restartUser(userId, /* foreground */ false);
24565     }
24566
24567     @Override
24568     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24569         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24570                 "scheduleApplicationInfoChanged()");
24571
24572         synchronized (this) {
24573             final long origId = Binder.clearCallingIdentity();
24574             try {
24575                 updateApplicationInfoLocked(packageNames, userId);
24576             } finally {
24577                 Binder.restoreCallingIdentity(origId);
24578             }
24579         }
24580     }
24581
24582     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24583         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24584         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24585             final ProcessRecord app = mLruProcesses.get(i);
24586             if (app.thread == null) {
24587                 continue;
24588             }
24589
24590             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24591                 continue;
24592             }
24593
24594             final int packageCount = app.pkgList.size();
24595             for (int j = 0; j < packageCount; j++) {
24596                 final String packageName = app.pkgList.keyAt(j);
24597                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24598                     try {
24599                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24600                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24601                         if (ai != null) {
24602                             app.thread.scheduleApplicationInfoChanged(ai);
24603                         }
24604                     } catch (RemoteException e) {
24605                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24606                                     packageName, app));
24607                     }
24608                 }
24609             }
24610         }
24611     }
24612
24613     /**
24614      * Attach an agent to the specified process (proces name or PID)
24615      */
24616     public void attachAgent(String process, String path) {
24617         try {
24618             synchronized (this) {
24619                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24620                 if (proc == null || proc.thread == null) {
24621                     throw new IllegalArgumentException("Unknown process: " + process);
24622                 }
24623
24624                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24625                 if (!isDebuggable) {
24626                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24627                         throw new SecurityException("Process not debuggable: " + proc);
24628                     }
24629                 }
24630
24631                 proc.thread.attachAgent(path);
24632             }
24633         } catch (RemoteException e) {
24634             throw new IllegalStateException("Process disappeared");
24635         }
24636     }
24637
24638     @VisibleForTesting
24639     public static class Injector {
24640         private NetworkManagementInternal mNmi;
24641
24642         public Context getContext() {
24643             return null;
24644         }
24645
24646         public AppOpsService getAppOpsService(File file, Handler handler) {
24647             return new AppOpsService(file, handler);
24648         }
24649
24650         public Handler getUiHandler(ActivityManagerService service) {
24651             return service.new UiHandler();
24652         }
24653
24654         public boolean isNetworkRestrictedForUid(int uid) {
24655             if (ensureHasNetworkManagementInternal()) {
24656                 return mNmi.isNetworkRestrictedForUid(uid);
24657             }
24658             return false;
24659         }
24660
24661         private boolean ensureHasNetworkManagementInternal() {
24662             if (mNmi == null) {
24663                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24664             }
24665             return mNmi != null;
24666         }
24667     }
24668
24669     @Override
24670     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24671             throws RemoteException {
24672         synchronized (this) {
24673             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24674             if (r == null) {
24675                 return;
24676             }
24677             final long origId = Binder.clearCallingIdentity();
24678             try {
24679                 r.setShowWhenLocked(showWhenLocked);
24680             } finally {
24681                 Binder.restoreCallingIdentity(origId);
24682             }
24683         }
24684     }
24685
24686     @Override
24687     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24688         synchronized (this) {
24689             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24690             if (r == null) {
24691                 return;
24692             }
24693             final long origId = Binder.clearCallingIdentity();
24694             try {
24695                 r.setTurnScreenOn(turnScreenOn);
24696             } finally {
24697                 Binder.restoreCallingIdentity(origId);
24698             }
24699         }
24700     }
24701 }