OSDN Git Service

Revert "DO NOT MERGE - Kill apps outright for API contract violations"
[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                         || UserHandle.isIsolated(procUid)) {
3579                     // Don't use an app process or different user process for system component.
3580                     continue;
3581                 }
3582                 return procs.valueAt(i);
3583             }
3584         }
3585         ProcessRecord proc = mProcessNames.get(processName, uid);
3586         if (false && proc != null && !keepIfLarge
3587                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3588                 && proc.lastCachedPss >= 4000) {
3589             // Turn this condition on to cause killing to happen regularly, for testing.
3590             if (proc.baseProcessTracker != null) {
3591                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3592             }
3593             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3594         } else if (proc != null && !keepIfLarge
3595                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3596                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3597             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3598             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3599                 if (proc.baseProcessTracker != null) {
3600                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3601                 }
3602                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3603             }
3604         }
3605         return proc;
3606     }
3607
3608     void notifyPackageUse(String packageName, int reason) {
3609         synchronized(this) {
3610             getPackageManagerInternalLocked().notifyPackageUse(packageName, reason);
3611         }
3612     }
3613
3614     boolean isNextTransitionForward() {
3615         int transit = mWindowManager.getPendingAppTransition();
3616         return transit == TRANSIT_ACTIVITY_OPEN
3617                 || transit == TRANSIT_TASK_OPEN
3618                 || transit == TRANSIT_TASK_TO_FRONT;
3619     }
3620
3621     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3622             String processName, String abiOverride, int uid, Runnable crashHandler) {
3623         synchronized(this) {
3624             ApplicationInfo info = new ApplicationInfo();
3625             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3626             // For isolated processes, the former contains the parent's uid and the latter the
3627             // actual uid of the isolated process.
3628             // In the special case introduced by this method (which is, starting an isolated
3629             // process directly from the SystemServer without an actual parent app process) the
3630             // closest thing to a parent's uid is SYSTEM_UID.
3631             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3632             // the |isolated| logic in the ProcessRecord constructor.
3633             info.uid = SYSTEM_UID;
3634             info.processName = processName;
3635             info.className = entryPoint;
3636             info.packageName = "android";
3637             info.seInfoUser = SELinuxUtil.COMPLETE_STR;
3638             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3639                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3640                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3641                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3642                     crashHandler);
3643             return proc != null ? proc.pid : 0;
3644         }
3645     }
3646
3647     final ProcessRecord startProcessLocked(String processName,
3648             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3649             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3650             boolean isolated, boolean keepIfLarge) {
3651         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3652                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3653                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3654                 null /* crashHandler */);
3655     }
3656
3657     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3658             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3659             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3660             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3661         long startTime = SystemClock.elapsedRealtime();
3662         ProcessRecord app;
3663         if (!isolated) {
3664             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3665             checkTime(startTime, "startProcess: after getProcessRecord");
3666
3667             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3668                 // If we are in the background, then check to see if this process
3669                 // is bad.  If so, we will just silently fail.
3670                 if (mAppErrors.isBadProcessLocked(info)) {
3671                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3672                             + "/" + info.processName);
3673                     return null;
3674                 }
3675             } else {
3676                 // When the user is explicitly starting a process, then clear its
3677                 // crash count so that we won't make it bad until they see at
3678                 // least one crash dialog again, and make the process good again
3679                 // if it had been bad.
3680                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3681                         + "/" + info.processName);
3682                 mAppErrors.resetProcessCrashTimeLocked(info);
3683                 if (mAppErrors.isBadProcessLocked(info)) {
3684                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3685                             UserHandle.getUserId(info.uid), info.uid,
3686                             info.processName);
3687                     mAppErrors.clearBadProcessLocked(info);
3688                     if (app != null) {
3689                         app.bad = false;
3690                     }
3691                 }
3692             }
3693         } else {
3694             // If this is an isolated process, it can't re-use an existing process.
3695             app = null;
3696         }
3697
3698         // We don't have to do anything more if:
3699         // (1) There is an existing application record; and
3700         // (2) The caller doesn't think it is dead, OR there is no thread
3701         //     object attached to it so we know it couldn't have crashed; and
3702         // (3) There is a pid assigned to it, so it is either starting or
3703         //     already running.
3704         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3705                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3706                 + " thread=" + (app != null ? app.thread : null)
3707                 + " pid=" + (app != null ? app.pid : -1));
3708         if (app != null && app.pid > 0) {
3709             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3710                 // We already have the app running, or are waiting for it to
3711                 // come up (we have a pid but not yet its thread), so keep it.
3712                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3713                 // If this is a new package in the process, add the package to the list
3714                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3715                 checkTime(startTime, "startProcess: done, added package to proc");
3716                 return app;
3717             }
3718
3719             // An application record is attached to a previous process,
3720             // clean it up now.
3721             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3722             checkTime(startTime, "startProcess: bad proc running, killing");
3723             killProcessGroup(app.uid, app.pid);
3724             handleAppDiedLocked(app, true, true);
3725             checkTime(startTime, "startProcess: done killing old proc");
3726         }
3727
3728         String hostingNameStr = hostingName != null
3729                 ? hostingName.flattenToShortString() : null;
3730
3731         if (app == null) {
3732             checkTime(startTime, "startProcess: creating new process record");
3733             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3734             if (app == null) {
3735                 Slog.w(TAG, "Failed making new process record for "
3736                         + processName + "/" + info.uid + " isolated=" + isolated);
3737                 return null;
3738             }
3739             app.crashHandler = crashHandler;
3740             checkTime(startTime, "startProcess: done creating new process record");
3741         } else {
3742             // If this is a new package in the process, add the package to the list
3743             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3744             checkTime(startTime, "startProcess: added package to existing proc");
3745         }
3746
3747         // If the system is not ready yet, then hold off on starting this
3748         // process until it is.
3749         if (!mProcessesReady
3750                 && !isAllowedWhileBooting(info)
3751                 && !allowWhileBooting) {
3752             if (!mProcessesOnHold.contains(app)) {
3753                 mProcessesOnHold.add(app);
3754             }
3755             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3756                     "System not ready, putting on hold: " + app);
3757             checkTime(startTime, "startProcess: returning with proc on hold");
3758             return app;
3759         }
3760
3761         checkTime(startTime, "startProcess: stepping in to startProcess");
3762         startProcessLocked(
3763                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3764         checkTime(startTime, "startProcess: done starting proc!");
3765         return (app.pid != 0) ? app : null;
3766     }
3767
3768     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3769         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3770     }
3771
3772     private final void startProcessLocked(ProcessRecord app,
3773             String hostingType, String hostingNameStr) {
3774         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3775                 null /* entryPoint */, null /* entryPointArgs */);
3776     }
3777
3778     private final void startProcessLocked(ProcessRecord app, String hostingType,
3779             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3780         long startTime = SystemClock.elapsedRealtime();
3781         if (app.pid > 0 && app.pid != MY_PID) {
3782             checkTime(startTime, "startProcess: removing from pids map");
3783             synchronized (mPidsSelfLocked) {
3784                 mPidsSelfLocked.remove(app.pid);
3785                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3786             }
3787             checkTime(startTime, "startProcess: done removing from pids map");
3788             app.setPid(0);
3789         }
3790
3791         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3792                 "startProcessLocked removing on hold: " + app);
3793         mProcessesOnHold.remove(app);
3794
3795         checkTime(startTime, "startProcess: starting to update cpu stats");
3796         updateCpuStats();
3797         checkTime(startTime, "startProcess: done updating cpu stats");
3798
3799         try {
3800             try {
3801                 final int userId = UserHandle.getUserId(app.uid);
3802                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3803             } catch (RemoteException e) {
3804                 throw e.rethrowAsRuntimeException();
3805             }
3806
3807             int uid = app.uid;
3808             int[] gids = null;
3809             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3810             if (!app.isolated) {
3811                 int[] permGids = null;
3812                 try {
3813                     checkTime(startTime, "startProcess: getting gids from package manager");
3814                     final IPackageManager pm = AppGlobals.getPackageManager();
3815                     permGids = pm.getPackageGids(app.info.packageName,
3816                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3817                     StorageManagerInternal storageManagerInternal = LocalServices.getService(
3818                             StorageManagerInternal.class);
3819                     mountExternal = storageManagerInternal.getExternalStorageMountMode(uid,
3820                             app.info.packageName);
3821                 } catch (RemoteException e) {
3822                     throw e.rethrowAsRuntimeException();
3823                 }
3824
3825                 /*
3826                  * Add shared application and profile GIDs so applications can share some
3827                  * resources like shared libraries and access user-wide resources
3828                  */
3829                 if (ArrayUtils.isEmpty(permGids)) {
3830                     gids = new int[3];
3831                 } else {
3832                     gids = new int[permGids.length + 3];
3833                     System.arraycopy(permGids, 0, gids, 3, permGids.length);
3834                 }
3835                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3836                 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
3837                 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3838             }
3839             checkTime(startTime, "startProcess: building args");
3840             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3841                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3842                         && mTopComponent != null
3843                         && app.processName.equals(mTopComponent.getPackageName())) {
3844                     uid = 0;
3845                 }
3846                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3847                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3848                     uid = 0;
3849                 }
3850             }
3851             int debugFlags = 0;
3852             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3853                 debugFlags |= Zygote.DEBUG_ENABLE_JDWP;
3854                 debugFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE;
3855                 // Also turn on CheckJNI for debuggable apps. It's quite
3856                 // awkward to turn on otherwise.
3857                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3858             }
3859             // Run the app in safe mode if its manifest requests so or the
3860             // system is booted in safe mode.
3861             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3862                 mSafeMode == true) {
3863                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3864             }
3865             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3866                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3867             }
3868             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3869             if ("true".equals(genDebugInfoProperty)) {
3870                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3871             }
3872             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3873                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3874             }
3875             if ("1".equals(SystemProperties.get("debug.assert"))) {
3876                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3877             }
3878             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3879                 // Enable all debug flags required by the native debugger.
3880                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3881                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3882                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3883                 mNativeDebuggingApp = null;
3884             }
3885
3886             String invokeWith = null;
3887             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3888                 // Debuggable apps may include a wrapper script with their library directory.
3889                 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
3890                 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3891                 try {
3892                     if (new File(wrapperFileName).exists()) {
3893                         invokeWith = "/system/bin/logwrapper " + wrapperFileName;
3894                     }
3895                 } finally {
3896                     StrictMode.setThreadPolicy(oldPolicy);
3897                 }
3898             }
3899
3900             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3901             if (requiredAbi == null) {
3902                 requiredAbi = Build.SUPPORTED_ABIS[0];
3903             }
3904
3905             String instructionSet = null;
3906             if (app.info.primaryCpuAbi != null) {
3907                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3908             }
3909
3910             app.gids = gids;
3911             app.requiredAbi = requiredAbi;
3912             app.instructionSet = instructionSet;
3913
3914             // the per-user SELinux context must be set
3915             if (TextUtils.isEmpty(app.info.seInfoUser)) {
3916                 Slog.wtf(TAG, "SELinux tag not defined",
3917                         new IllegalStateException("SELinux tag not defined for "
3918                         + app.info.packageName + " (uid " + app.uid + ")"));
3919             }
3920             final String seInfo = app.info.seInfo
3921                     + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
3922             // Start the process.  It will either succeed and return a result containing
3923             // the PID of the new process, or else throw a RuntimeException.
3924             boolean isActivityProcess = (entryPoint == null);
3925             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3926             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3927                     app.processName);
3928             checkTime(startTime, "startProcess: asking zygote to start proc");
3929             ProcessStartResult startResult;
3930             if (hostingType.equals("webview_service")) {
3931                 startResult = startWebView(entryPoint,
3932                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3933                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3934                         app.info.dataDir, null, entryPointArgs);
3935             } else {
3936                 startResult = Process.start(entryPoint,
3937                         app.processName, uid, uid, gids, debugFlags, mountExternal,
3938                         app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
3939                         app.info.dataDir, invokeWith, entryPointArgs);
3940             }
3941             checkTime(startTime, "startProcess: returned from zygote!");
3942             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3943
3944             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3945             checkTime(startTime, "startProcess: done updating battery stats");
3946
3947             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3948                     UserHandle.getUserId(uid), startResult.pid, uid,
3949                     app.processName, hostingType,
3950                     hostingNameStr != null ? hostingNameStr : "");
3951
3952             try {
3953                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3954                         seInfo, app.info.sourceDir, startResult.pid);
3955             } catch (RemoteException ex) {
3956                 // Ignore
3957             }
3958
3959             if (app.persistent) {
3960                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3961             }
3962
3963             checkTime(startTime, "startProcess: building log message");
3964             StringBuilder buf = mStringBuilder;
3965             buf.setLength(0);
3966             buf.append("Start proc ");
3967             buf.append(startResult.pid);
3968             buf.append(':');
3969             buf.append(app.processName);
3970             buf.append('/');
3971             UserHandle.formatUid(buf, uid);
3972             if (!isActivityProcess) {
3973                 buf.append(" [");
3974                 buf.append(entryPoint);
3975                 buf.append("]");
3976             }
3977             buf.append(" for ");
3978             buf.append(hostingType);
3979             if (hostingNameStr != null) {
3980                 buf.append(" ");
3981                 buf.append(hostingNameStr);
3982             }
3983             Slog.i(TAG, buf.toString());
3984             app.setPid(startResult.pid);
3985             app.usingWrapper = startResult.usingWrapper;
3986             app.removed = false;
3987             app.killed = false;
3988             app.killedByAm = false;
3989             checkTime(startTime, "startProcess: starting to update pids map");
3990             ProcessRecord oldApp;
3991             synchronized (mPidsSelfLocked) {
3992                 oldApp = mPidsSelfLocked.get(startResult.pid);
3993             }
3994             // If there is already an app occupying that pid that hasn't been cleaned up
3995             if (oldApp != null && !app.isolated) {
3996                 // Clean up anything relating to this pid first
3997                 Slog.w(TAG, "Reusing pid " + startResult.pid
3998                         + " while app is still mapped to it");
3999                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
4000                         true /*replacingPid*/);
4001             }
4002             synchronized (mPidsSelfLocked) {
4003                 this.mPidsSelfLocked.put(startResult.pid, app);
4004                 if (isActivityProcess) {
4005                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
4006                     msg.obj = app;
4007                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
4008                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
4009                 }
4010             }
4011             checkTime(startTime, "startProcess: done updating pids map");
4012         } catch (RuntimeException e) {
4013             Slog.e(TAG, "Failure starting process " + app.processName, e);
4014
4015             // Something went very wrong while trying to start this process; one
4016             // common case is when the package is frozen due to an active
4017             // upgrade. To recover, clean up any active bookkeeping related to
4018             // starting this process. (We already invoked this method once when
4019             // the package was initially frozen through KILL_APPLICATION_MSG, so
4020             // it doesn't hurt to use it again.)
4021             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
4022                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
4023         }
4024     }
4025
4026     void updateUsageStats(ActivityRecord component, boolean resumed) {
4027         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
4028                 "updateUsageStats: comp=" + component + "res=" + resumed);
4029         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4030         if (resumed) {
4031             if (mUsageStatsService != null) {
4032                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4033                         UsageEvents.Event.MOVE_TO_FOREGROUND);
4034             }
4035             synchronized (stats) {
4036                 stats.noteActivityResumedLocked(component.app.uid);
4037             }
4038         } else {
4039             if (mUsageStatsService != null) {
4040                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
4041                         UsageEvents.Event.MOVE_TO_BACKGROUND);
4042             }
4043             synchronized (stats) {
4044                 stats.noteActivityPausedLocked(component.app.uid);
4045             }
4046         }
4047     }
4048
4049     Intent getHomeIntent() {
4050         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
4051         intent.setComponent(mTopComponent);
4052         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
4053         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
4054             intent.addCategory(Intent.CATEGORY_HOME);
4055         }
4056         return intent;
4057     }
4058
4059     boolean startHomeActivityLocked(int userId, String reason) {
4060         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
4061                 && mTopAction == null) {
4062             // We are running in factory test mode, but unable to find
4063             // the factory test app, so just sit around displaying the
4064             // error message and don't try to start anything.
4065             return false;
4066         }
4067         Intent intent = getHomeIntent();
4068         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
4069         if (aInfo != null) {
4070             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
4071             // Don't do this if the home app is currently being
4072             // instrumented.
4073             aInfo = new ActivityInfo(aInfo);
4074             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
4075             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
4076                     aInfo.applicationInfo.uid, true);
4077             if (app == null || app.instr == null) {
4078                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
4079                 final int resolvedUserId = UserHandle.getUserId(aInfo.applicationInfo.uid);
4080                 // For ANR debugging to verify if the user activity is the one that actually
4081                 // launched.
4082                 final String myReason = reason + ":" + userId + ":" + resolvedUserId;
4083                 mActivityStarter.startHomeActivityLocked(intent, aInfo, myReason);
4084             }
4085         } else {
4086             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
4087         }
4088
4089         return true;
4090     }
4091
4092     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
4093         ActivityInfo ai = null;
4094         ComponentName comp = intent.getComponent();
4095         try {
4096             if (comp != null) {
4097                 // Factory test.
4098                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
4099             } else {
4100                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
4101                         intent,
4102                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
4103                         flags, userId);
4104
4105                 if (info != null) {
4106                     ai = info.activityInfo;
4107                 }
4108             }
4109         } catch (RemoteException e) {
4110             // ignore
4111         }
4112
4113         return ai;
4114     }
4115
4116     /**
4117      * Starts the "new version setup screen" if appropriate.
4118      */
4119     void startSetupActivityLocked() {
4120         // Only do this once per boot.
4121         if (mCheckedForSetup) {
4122             return;
4123         }
4124
4125         // We will show this screen if the current one is a different
4126         // version than the last one shown, and we are not running in
4127         // low-level factory test mode.
4128         final ContentResolver resolver = mContext.getContentResolver();
4129         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
4130                 Settings.Global.getInt(resolver,
4131                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
4132             mCheckedForSetup = true;
4133
4134             // See if we should be showing the platform update setup UI.
4135             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4136             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4137                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4138             if (!ris.isEmpty()) {
4139                 final ResolveInfo ri = ris.get(0);
4140                 String vers = ri.activityInfo.metaData != null
4141                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4142                         : null;
4143                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4144                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4145                             Intent.METADATA_SETUP_VERSION);
4146                 }
4147                 String lastVers = Settings.Secure.getString(
4148                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4149                 if (vers != null && !vers.equals(lastVers)) {
4150                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4151                     intent.setComponent(new ComponentName(
4152                             ri.activityInfo.packageName, ri.activityInfo.name));
4153                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4154                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4155                             null, 0, 0, 0, null, false, false, null, null, "startSetupActivity");
4156                 }
4157             }
4158         }
4159     }
4160
4161     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4162         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4163     }
4164
4165     void enforceNotIsolatedCaller(String caller) {
4166         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4167             throw new SecurityException("Isolated process not allowed to call " + caller);
4168         }
4169     }
4170
4171     void enforceShellRestriction(String restriction, int userHandle) {
4172         if (Binder.getCallingUid() == SHELL_UID) {
4173             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4174                 throw new SecurityException("Shell does not have permission to access user "
4175                         + userHandle);
4176             }
4177         }
4178     }
4179
4180     @Override
4181     public int getFrontActivityScreenCompatMode() {
4182         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4183         synchronized (this) {
4184             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4185         }
4186     }
4187
4188     @Override
4189     public void setFrontActivityScreenCompatMode(int mode) {
4190         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4191                 "setFrontActivityScreenCompatMode");
4192         synchronized (this) {
4193             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4194         }
4195     }
4196
4197     @Override
4198     public int getPackageScreenCompatMode(String packageName) {
4199         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4200         synchronized (this) {
4201             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4202         }
4203     }
4204
4205     @Override
4206     public void setPackageScreenCompatMode(String packageName, int mode) {
4207         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4208                 "setPackageScreenCompatMode");
4209         synchronized (this) {
4210             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4211         }
4212     }
4213
4214     @Override
4215     public boolean getPackageAskScreenCompat(String packageName) {
4216         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4217         synchronized (this) {
4218             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4219         }
4220     }
4221
4222     @Override
4223     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4224         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4225                 "setPackageAskScreenCompat");
4226         synchronized (this) {
4227             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4228         }
4229     }
4230
4231     private boolean hasUsageStatsPermission(String callingPackage) {
4232         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4233                 Binder.getCallingUid(), callingPackage);
4234         if (mode == AppOpsManager.MODE_DEFAULT) {
4235             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4236                     == PackageManager.PERMISSION_GRANTED;
4237         }
4238         return mode == AppOpsManager.MODE_ALLOWED;
4239     }
4240
4241     @Override
4242     public int getPackageProcessState(String packageName, String callingPackage) {
4243         if (!hasUsageStatsPermission(callingPackage)) {
4244             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
4245                     "getPackageProcessState");
4246         }
4247
4248         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4249         synchronized (this) {
4250             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4251                 final ProcessRecord proc = mLruProcesses.get(i);
4252                 if (procState > proc.setProcState) {
4253                     if (proc.pkgList.containsKey(packageName) ||
4254                             (proc.pkgDeps != null && proc.pkgDeps.contains(packageName))) {
4255                         procState = proc.setProcState;
4256                     }
4257                 }
4258             }
4259         }
4260         return procState;
4261     }
4262
4263     @Override
4264     public boolean setProcessMemoryTrimLevel(String process, int userId, int level)
4265             throws RemoteException {
4266         synchronized (this) {
4267             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4268             if (app == null) {
4269                 throw new IllegalArgumentException("Unknown process: " + process);
4270             }
4271             if (app.thread == null) {
4272                 throw new IllegalArgumentException("Process has no app thread");
4273             }
4274             if (app.trimMemoryLevel >= level) {
4275                 throw new IllegalArgumentException(
4276                         "Unable to set a higher trim level than current level");
4277             }
4278             if (!(level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4279                     app.curProcState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)) {
4280                 throw new IllegalArgumentException("Unable to set a background trim level "
4281                     + "on a foreground process");
4282             }
4283             app.thread.scheduleTrimMemory(level);
4284             app.trimMemoryLevel = level;
4285             return true;
4286         }
4287     }
4288
4289     private void dispatchProcessesChanged() {
4290         int N;
4291         synchronized (this) {
4292             N = mPendingProcessChanges.size();
4293             if (mActiveProcessChanges.length < N) {
4294                 mActiveProcessChanges = new ProcessChangeItem[N];
4295             }
4296             mPendingProcessChanges.toArray(mActiveProcessChanges);
4297             mPendingProcessChanges.clear();
4298             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4299                     "*** Delivering " + N + " process changes");
4300         }
4301
4302         int i = mProcessObservers.beginBroadcast();
4303         while (i > 0) {
4304             i--;
4305             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4306             if (observer != null) {
4307                 try {
4308                     for (int j=0; j<N; j++) {
4309                         ProcessChangeItem item = mActiveProcessChanges[j];
4310                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4311                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4312                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4313                                     + item.uid + ": " + item.foregroundActivities);
4314                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4315                                     item.foregroundActivities);
4316                         }
4317                     }
4318                 } catch (RemoteException e) {
4319                 }
4320             }
4321         }
4322         mProcessObservers.finishBroadcast();
4323
4324         synchronized (this) {
4325             for (int j=0; j<N; j++) {
4326                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4327             }
4328         }
4329     }
4330
4331     private void dispatchProcessDied(int pid, int uid) {
4332         int i = mProcessObservers.beginBroadcast();
4333         while (i > 0) {
4334             i--;
4335             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4336             if (observer != null) {
4337                 try {
4338                     observer.onProcessDied(pid, uid);
4339                 } catch (RemoteException e) {
4340                 }
4341             }
4342         }
4343         mProcessObservers.finishBroadcast();
4344     }
4345
4346     @VisibleForTesting
4347     void dispatchUidsChanged() {
4348         int N;
4349         synchronized (this) {
4350             N = mPendingUidChanges.size();
4351             if (mActiveUidChanges.length < N) {
4352                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4353             }
4354             for (int i=0; i<N; i++) {
4355                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4356                 mActiveUidChanges[i] = change;
4357                 if (change.uidRecord != null) {
4358                     change.uidRecord.pendingChange = null;
4359                     change.uidRecord = null;
4360                 }
4361             }
4362             mPendingUidChanges.clear();
4363             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4364                     "*** Delivering " + N + " uid changes");
4365         }
4366
4367         int i = mUidObservers.beginBroadcast();
4368         while (i > 0) {
4369             i--;
4370             dispatchUidsChangedForObserver(mUidObservers.getBroadcastItem(i),
4371                     (UidObserverRegistration) mUidObservers.getBroadcastCookie(i), N);
4372         }
4373         mUidObservers.finishBroadcast();
4374
4375         if (VALIDATE_UID_STATES && mUidObservers.getRegisteredCallbackCount() > 0) {
4376             for (int j = 0; j < N; ++j) {
4377                 final UidRecord.ChangeItem item = mActiveUidChanges[j];
4378                 if ((item.change & UidRecord.CHANGE_GONE) != 0) {
4379                     mValidateUids.remove(item.uid);
4380                 } else {
4381                     UidRecord validateUid = mValidateUids.get(item.uid);
4382                     if (validateUid == null) {
4383                         validateUid = new UidRecord(item.uid);
4384                         mValidateUids.put(item.uid, validateUid);
4385                     }
4386                     if ((item.change & UidRecord.CHANGE_IDLE) != 0) {
4387                         validateUid.idle = true;
4388                     } else if ((item.change & UidRecord.CHANGE_ACTIVE) != 0) {
4389                         validateUid.idle = false;
4390                     }
4391                     validateUid.curProcState = validateUid.setProcState = item.processState;
4392                     validateUid.lastDispatchedProcStateSeq = item.procStateSeq;
4393                 }
4394             }
4395         }
4396
4397         synchronized (this) {
4398             for (int j = 0; j < N; j++) {
4399                 mAvailUidChanges.add(mActiveUidChanges[j]);
4400             }
4401         }
4402     }
4403
4404     private void dispatchUidsChangedForObserver(IUidObserver observer,
4405             UidObserverRegistration reg, int changesSize) {
4406         if (observer == null) {
4407             return;
4408         }
4409         try {
4410             for (int j = 0; j < changesSize; j++) {
4411                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4412                 final int change = item.change;
4413                 if (change == UidRecord.CHANGE_PROCSTATE &&
4414                         (reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) {
4415                     // No-op common case: no significant change, the observer is not
4416                     // interested in all proc state changes.
4417                     continue;
4418                 }
4419                 if ((change & UidRecord.CHANGE_IDLE) != 0) {
4420                     if ((reg.which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4421                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4422                                 "UID idle uid=" + item.uid);
4423                         observer.onUidIdle(item.uid, item.ephemeral);
4424                     }
4425                 } else if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
4426                     if ((reg.which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4427                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4428                                 "UID active uid=" + item.uid);
4429                         observer.onUidActive(item.uid);
4430                     }
4431                 }
4432                 if ((reg.which & ActivityManager.UID_OBSERVER_CACHED) != 0) {
4433                     if ((change & UidRecord.CHANGE_CACHED) != 0) {
4434                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4435                                 "UID cached uid=" + item.uid);
4436                         observer.onUidCachedChanged(item.uid, true);
4437                     } else if ((change & UidRecord.CHANGE_UNCACHED) != 0) {
4438                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4439                                 "UID active uid=" + item.uid);
4440                         observer.onUidCachedChanged(item.uid, false);
4441                     }
4442                 }
4443                 if ((change & UidRecord.CHANGE_GONE) != 0) {
4444                     if ((reg.which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4445                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4446                                 "UID gone uid=" + item.uid);
4447                         observer.onUidGone(item.uid, item.ephemeral);
4448                     }
4449                     if (reg.lastProcStates != null) {
4450                         reg.lastProcStates.delete(item.uid);
4451                     }
4452                 } else {
4453                     if ((reg.which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4454                         if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4455                                 "UID CHANGED uid=" + item.uid
4456                                         + ": " + item.processState);
4457                         boolean doReport = true;
4458                         if (reg.cutpoint >= ActivityManager.MIN_PROCESS_STATE) {
4459                             final int lastState = reg.lastProcStates.get(item.uid,
4460                                     ActivityManager.PROCESS_STATE_UNKNOWN);
4461                             if (lastState != ActivityManager.PROCESS_STATE_UNKNOWN) {
4462                                 final boolean lastAboveCut = lastState <= reg.cutpoint;
4463                                 final boolean newAboveCut = item.processState <= reg.cutpoint;
4464                                 doReport = lastAboveCut != newAboveCut;
4465                             } else {
4466                                 doReport = item.processState
4467                                         != ActivityManager.PROCESS_STATE_NONEXISTENT;
4468                             }
4469                         }
4470                         if (doReport) {
4471                             if (reg.lastProcStates != null) {
4472                                 reg.lastProcStates.put(item.uid, item.processState);
4473                             }
4474                             observer.onUidStateChanged(item.uid, item.processState,
4475                                     item.procStateSeq);
4476                         }
4477                     }
4478                 }
4479             }
4480         } catch (RemoteException e) {
4481         }
4482     }
4483
4484     void dispatchOomAdjObserver(String msg) {
4485         OomAdjObserver observer;
4486         synchronized (this) {
4487             observer = mCurOomAdjObserver;
4488         }
4489
4490         if (observer != null) {
4491             observer.onOomAdjMessage(msg);
4492         }
4493     }
4494
4495     void setOomAdjObserver(int uid, OomAdjObserver observer) {
4496         synchronized (this) {
4497             mCurOomAdjUid = uid;
4498             mCurOomAdjObserver = observer;
4499         }
4500     }
4501
4502     void clearOomAdjObserver() {
4503         synchronized (this) {
4504             mCurOomAdjUid = -1;
4505             mCurOomAdjObserver = null;
4506         }
4507     }
4508
4509     void reportOomAdjMessageLocked(String tag, String msg) {
4510         Slog.d(tag, msg);
4511         if (mCurOomAdjObserver != null) {
4512             mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg).sendToTarget();
4513         }
4514     }
4515
4516     @Override
4517     public final int startActivity(IApplicationThread caller, String callingPackage,
4518             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4519             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4520         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4521                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4522                 UserHandle.getCallingUserId());
4523     }
4524
4525     @Override
4526     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4527             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4528             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4529         enforceNotIsolatedCaller("startActivity");
4530         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4531                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4532         // TODO: Switch to user app stacks here.
4533         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4534                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4535                 profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
4536     }
4537
4538     @Override
4539     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4540             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4541             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4542             int userId) {
4543
4544         // This is very dangerous -- it allows you to perform a start activity (including
4545         // permission grants) as any app that may launch one of your own activities.  So
4546         // we will only allow this to be done from activities that are part of the core framework,
4547         // and then only when they are running as the system.
4548         final ActivityRecord sourceRecord;
4549         final int targetUid;
4550         final String targetPackage;
4551         synchronized (this) {
4552             if (resultTo == null) {
4553                 throw new SecurityException("Must be called from an activity");
4554             }
4555             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4556             if (sourceRecord == null) {
4557                 throw new SecurityException("Called with bad activity token: " + resultTo);
4558             }
4559             if (!sourceRecord.info.packageName.equals("android")) {
4560                 throw new SecurityException(
4561                         "Must be called from an activity that is declared in the android package");
4562             }
4563             if (sourceRecord.app == null) {
4564                 throw new SecurityException("Called without a process attached to activity");
4565             }
4566             if (UserHandle.getAppId(sourceRecord.app.uid) != SYSTEM_UID) {
4567                 // This is still okay, as long as this activity is running under the
4568                 // uid of the original calling activity.
4569                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4570                     throw new SecurityException(
4571                             "Calling activity in uid " + sourceRecord.app.uid
4572                                     + " must be system uid or original calling uid "
4573                                     + sourceRecord.launchedFromUid);
4574                 }
4575             }
4576             if (ignoreTargetSecurity) {
4577                 if (intent.getComponent() == null) {
4578                     throw new SecurityException(
4579                             "Component must be specified with ignoreTargetSecurity");
4580                 }
4581                 if (intent.getSelector() != null) {
4582                     throw new SecurityException(
4583                             "Selector not allowed with ignoreTargetSecurity");
4584                 }
4585             }
4586             targetUid = sourceRecord.launchedFromUid;
4587             targetPackage = sourceRecord.launchedFromPackage;
4588         }
4589
4590         if (userId == UserHandle.USER_NULL) {
4591             userId = UserHandle.getUserId(sourceRecord.app.uid);
4592         }
4593
4594         // TODO: Switch to user app stacks here.
4595         try {
4596             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4597                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4598                     null, null, bOptions, ignoreTargetSecurity, userId, null,
4599                     "startActivityAsCaller");
4600             return ret;
4601         } catch (SecurityException e) {
4602             // XXX need to figure out how to propagate to original app.
4603             // A SecurityException here is generally actually a fault of the original
4604             // calling activity (such as a fairly granting permissions), so propagate it
4605             // back to them.
4606             /*
4607             StringBuilder msg = new StringBuilder();
4608             msg.append("While launching");
4609             msg.append(intent.toString());
4610             msg.append(": ");
4611             msg.append(e.getMessage());
4612             */
4613             throw e;
4614         }
4615     }
4616
4617     @Override
4618     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4619             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4620             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4621         enforceNotIsolatedCaller("startActivityAndWait");
4622         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4623                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4624         WaitResult res = new WaitResult();
4625         // TODO: Switch to user app stacks here.
4626         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4627                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4628                 bOptions, false, userId, null, "startActivityAndWait");
4629         return res;
4630     }
4631
4632     @Override
4633     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4634             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4635             int startFlags, Configuration config, Bundle bOptions, int userId) {
4636         enforceNotIsolatedCaller("startActivityWithConfig");
4637         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4638                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4639         // TODO: Switch to user app stacks here.
4640         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4641                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4642                 null, null, config, bOptions, false, userId, null, "startActivityWithConfig");
4643         return ret;
4644     }
4645
4646     @Override
4647     public int startActivityIntentSender(IApplicationThread caller, IIntentSender target,
4648             IBinder whitelistToken, Intent fillInIntent, String resolvedType, IBinder resultTo,
4649             String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4650             throws TransactionTooLargeException {
4651         enforceNotIsolatedCaller("startActivityIntentSender");
4652         // Refuse possible leaked file descriptors
4653         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4654             throw new IllegalArgumentException("File descriptors passed in Intent");
4655         }
4656
4657         if (!(target instanceof PendingIntentRecord)) {
4658             throw new IllegalArgumentException("Bad PendingIntent object");
4659         }
4660
4661         PendingIntentRecord pir = (PendingIntentRecord)target;
4662
4663         synchronized (this) {
4664             // If this is coming from the currently resumed activity, it is
4665             // effectively saying that app switches are allowed at this point.
4666             final ActivityStack stack = getFocusedStack();
4667             if (stack.mResumedActivity != null &&
4668                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4669                 mAppSwitchesAllowedTime = 0;
4670             }
4671         }
4672         int ret = pir.sendInner(0, fillInIntent, resolvedType, whitelistToken, null, null,
4673                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions);
4674         return ret;
4675     }
4676
4677     @Override
4678     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4679             Intent intent, String resolvedType, IVoiceInteractionSession session,
4680             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4681             Bundle bOptions, int userId) {
4682         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4683                 != PackageManager.PERMISSION_GRANTED) {
4684             String msg = "Permission Denial: startVoiceActivity() from pid="
4685                     + Binder.getCallingPid()
4686                     + ", uid=" + Binder.getCallingUid()
4687                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4688             Slog.w(TAG, msg);
4689             throw new SecurityException(msg);
4690         }
4691         if (session == null || interactor == null) {
4692             throw new NullPointerException("null session or interactor");
4693         }
4694         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4695                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4696         // TODO: Switch to user app stacks here.
4697         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4698                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4699                 null, bOptions, false, userId, null, "startVoiceActivity");
4700     }
4701
4702     @Override
4703     public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
4704             Intent intent, String resolvedType, Bundle bOptions, int userId) {
4705         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4706                 != PackageManager.PERMISSION_GRANTED) {
4707             final String msg = "Permission Denial: startAssistantActivity() from pid="
4708                     + Binder.getCallingPid()
4709                     + ", uid=" + Binder.getCallingUid()
4710                     + " requires " + Manifest.permission.BIND_VOICE_INTERACTION;
4711             Slog.w(TAG, msg);
4712             throw new SecurityException(msg);
4713         }
4714         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4715                 ALLOW_FULL_ONLY, "startAssistantActivity", null);
4716         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4717                 resolvedType, null, null, null, null, 0, 0, null, null, null, bOptions, false,
4718                 userId, null, "startAssistantActivity");
4719     }
4720
4721     @Override
4722     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4723             throws RemoteException {
4724         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4725         synchronized (this) {
4726             ActivityRecord activity = getFocusedStack().topActivity();
4727             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4728                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4729             }
4730             if (mRunningVoice != null || activity.getTask().voiceSession != null
4731                     || activity.voiceSession != null) {
4732                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4733                 return;
4734             }
4735             if (activity.pendingVoiceInteractionStart) {
4736                 Slog.w(TAG, "Pending start of voice interaction already.");
4737                 return;
4738             }
4739             activity.pendingVoiceInteractionStart = true;
4740         }
4741         LocalServices.getService(VoiceInteractionManagerInternal.class)
4742                 .startLocalVoiceInteraction(callingActivity, options);
4743     }
4744
4745     @Override
4746     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4747         LocalServices.getService(VoiceInteractionManagerInternal.class)
4748                 .stopLocalVoiceInteraction(callingActivity);
4749     }
4750
4751     @Override
4752     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4753         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4754                 .supportsLocalVoiceInteraction();
4755     }
4756
4757     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4758             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4759         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4760         if (activityToCallback == null) return;
4761         activityToCallback.setVoiceSessionLocked(voiceSession);
4762
4763         // Inform the activity
4764         try {
4765             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4766                     voiceInteractor);
4767             long token = Binder.clearCallingIdentity();
4768             try {
4769                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4770             } finally {
4771                 Binder.restoreCallingIdentity(token);
4772             }
4773             // TODO: VI Should we cache the activity so that it's easier to find later
4774             // rather than scan through all the stacks and activities?
4775         } catch (RemoteException re) {
4776             activityToCallback.clearVoiceSessionLocked();
4777             // TODO: VI Should this terminate the voice session?
4778         }
4779     }
4780
4781     @Override
4782     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4783         synchronized (this) {
4784             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4785                 if (keepAwake) {
4786                     mVoiceWakeLock.acquire();
4787                 } else {
4788                     mVoiceWakeLock.release();
4789                 }
4790             }
4791         }
4792     }
4793
4794     @Override
4795     public boolean startNextMatchingActivity(IBinder callingActivity,
4796             Intent intent, Bundle bOptions) {
4797         // Refuse possible leaked file descriptors
4798         if (intent != null && intent.hasFileDescriptors() == true) {
4799             throw new IllegalArgumentException("File descriptors passed in Intent");
4800         }
4801         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4802
4803         synchronized (this) {
4804             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4805             if (r == null) {
4806                 ActivityOptions.abort(options);
4807                 return false;
4808             }
4809             if (r.app == null || r.app.thread == null) {
4810                 // The caller is not running...  d'oh!
4811                 ActivityOptions.abort(options);
4812                 return false;
4813             }
4814             intent = new Intent(intent);
4815             // The caller is not allowed to change the data.
4816             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4817             // And we are resetting to find the next component...
4818             intent.setComponent(null);
4819
4820             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4821
4822             ActivityInfo aInfo = null;
4823             try {
4824                 List<ResolveInfo> resolves =
4825                     AppGlobals.getPackageManager().queryIntentActivities(
4826                             intent, r.resolvedType,
4827                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4828                             UserHandle.getCallingUserId()).getList();
4829
4830                 // Look for the original activity in the list...
4831                 final int N = resolves != null ? resolves.size() : 0;
4832                 for (int i=0; i<N; i++) {
4833                     ResolveInfo rInfo = resolves.get(i);
4834                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4835                             && rInfo.activityInfo.name.equals(r.info.name)) {
4836                         // We found the current one...  the next matching is
4837                         // after it.
4838                         i++;
4839                         if (i<N) {
4840                             aInfo = resolves.get(i).activityInfo;
4841                         }
4842                         if (debug) {
4843                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4844                                     + "/" + r.info.name);
4845                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4846                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4847                         }
4848                         break;
4849                     }
4850                 }
4851             } catch (RemoteException e) {
4852             }
4853
4854             if (aInfo == null) {
4855                 // Nobody who is next!
4856                 ActivityOptions.abort(options);
4857                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4858                 return false;
4859             }
4860
4861             intent.setComponent(new ComponentName(
4862                     aInfo.applicationInfo.packageName, aInfo.name));
4863             intent.setFlags(intent.getFlags()&~(
4864                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4865                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4866                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4867                     Intent.FLAG_ACTIVITY_NEW_TASK));
4868
4869             // Okay now we need to start the new activity, replacing the
4870             // currently running activity.  This is a little tricky because
4871             // we want to start the new one as if the current one is finished,
4872             // but not finish the current one first so that there is no flicker.
4873             // And thus...
4874             final boolean wasFinishing = r.finishing;
4875             r.finishing = true;
4876
4877             // Propagate reply information over to the new activity.
4878             final ActivityRecord resultTo = r.resultTo;
4879             final String resultWho = r.resultWho;
4880             final int requestCode = r.requestCode;
4881             r.resultTo = null;
4882             if (resultTo != null) {
4883                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4884             }
4885
4886             final long origId = Binder.clearCallingIdentity();
4887             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4888                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4889                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4890                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4891                     false, false, null, null, "startNextMatchingActivity");
4892             Binder.restoreCallingIdentity(origId);
4893
4894             r.finishing = wasFinishing;
4895             if (res != ActivityManager.START_SUCCESS) {
4896                 return false;
4897             }
4898             return true;
4899         }
4900     }
4901
4902     @Override
4903     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4904         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4905             String msg = "Permission Denial: startActivityFromRecents called without " +
4906                     START_TASKS_FROM_RECENTS;
4907             Slog.w(TAG, msg);
4908             throw new SecurityException(msg);
4909         }
4910         final long origId = Binder.clearCallingIdentity();
4911         try {
4912             synchronized (this) {
4913                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4914             }
4915         } finally {
4916             Binder.restoreCallingIdentity(origId);
4917         }
4918     }
4919
4920     final int startActivityInPackage(int uid, String callingPackage,
4921             Intent intent, String resolvedType, IBinder resultTo,
4922             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4923             TaskRecord inTask, String reason) {
4924
4925         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4926                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4927
4928         // TODO: Switch to user app stacks here.
4929         return mActivityStarter.startActivityMayWait(null, uid, ActivityStarter.PID_NULL, uid,
4930                 callingPackage, intent, resolvedType, null, null, resultTo, resultWho, requestCode,
4931                 startFlags, null, null, null, bOptions, false, userId, inTask, reason);
4932     }
4933
4934     @Override
4935     public final int startActivities(IApplicationThread caller, String callingPackage,
4936             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4937             int userId) {
4938         final String reason = "startActivities";
4939         enforceNotIsolatedCaller(reason);
4940         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4941                 userId, false, ALLOW_FULL_ONLY, reason, null);
4942         // TODO: Switch to user app stacks here.
4943         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4944                 resolvedTypes, resultTo, bOptions, userId, reason);
4945         return ret;
4946     }
4947
4948     final int startActivitiesInPackage(int uid, String callingPackage,
4949             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4950             Bundle bOptions, int userId) {
4951         return startActivitiesInPackage(uid, ActivityStarter.PID_NULL, UserHandle.USER_NULL,
4952                 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId);
4953     }
4954
4955     final int startActivitiesInPackage(int uid, int realCallingPid, int realCallingUid,
4956                                        String callingPackage, Intent[] intents, String[] resolvedTypes,
4957                                        IBinder resultTo, Bundle bOptions, int userId) {
4958
4959         final String reason = "startActivityInPackage";
4960         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4961                 userId, false, ALLOW_FULL_ONLY, reason, null);
4962         // TODO: Switch to user app stacks here.
4963         int ret = mActivityStarter.startActivities(null, uid, realCallingPid, realCallingUid,
4964                 callingPackage, intents, resolvedTypes, resultTo, bOptions, userId, reason);
4965         return ret;
4966     }
4967
4968     @Override
4969     public void reportActivityFullyDrawn(IBinder token, boolean restoredFromBundle) {
4970         synchronized (this) {
4971             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972             if (r == null) {
4973                 return;
4974             }
4975             r.reportFullyDrawnLocked(restoredFromBundle);
4976         }
4977     }
4978
4979     @Override
4980     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4981         synchronized (this) {
4982             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4983             if (r == null) {
4984                 return;
4985             }
4986             final long origId = Binder.clearCallingIdentity();
4987             try {
4988                 r.setRequestedOrientation(requestedOrientation);
4989             } finally {
4990                 Binder.restoreCallingIdentity(origId);
4991             }
4992         }
4993     }
4994
4995     @Override
4996     public int getRequestedOrientation(IBinder token) {
4997         synchronized (this) {
4998             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4999             if (r == null) {
5000                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
5001             }
5002             return r.getRequestedOrientation();
5003         }
5004     }
5005
5006     @Override
5007     public final void requestActivityRelaunch(IBinder token) {
5008         synchronized(this) {
5009             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5010             if (r == null) {
5011                 return;
5012             }
5013             final long origId = Binder.clearCallingIdentity();
5014             try {
5015                 r.forceNewConfig = true;
5016                 r.ensureActivityConfigurationLocked(0 /* globalChanges */,
5017                         true /* preserveWindow */);
5018             } finally {
5019                 Binder.restoreCallingIdentity(origId);
5020             }
5021         }
5022     }
5023
5024     /**
5025      * This is the internal entry point for handling Activity.finish().
5026      *
5027      * @param token The Binder token referencing the Activity we want to finish.
5028      * @param resultCode Result code, if any, from this Activity.
5029      * @param resultData Result data (Intent), if any, from this Activity.
5030      * @param finishTask Whether to finish the task associated with this Activity.
5031      *
5032      * @return Returns true if the activity successfully finished, or false if it is still running.
5033      */
5034     @Override
5035     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
5036             int finishTask) {
5037         // Refuse possible leaked file descriptors
5038         if (resultData != null && resultData.hasFileDescriptors() == true) {
5039             throw new IllegalArgumentException("File descriptors passed in Intent");
5040         }
5041
5042         synchronized(this) {
5043             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5044             if (r == null) {
5045                 return true;
5046             }
5047             // Keep track of the root activity of the task before we finish it
5048             TaskRecord tr = r.getTask();
5049             ActivityRecord rootR = tr.getRootActivity();
5050             if (rootR == null) {
5051                 Slog.w(TAG, "Finishing task with all activities already finished");
5052             }
5053             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
5054             // finish.
5055             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
5056                     mStackSupervisor.isLastLockedTask(tr)) {
5057                 Slog.i(TAG, "Not finishing task in lock task mode");
5058                 mStackSupervisor.showLockTaskToast();
5059                 return false;
5060             }
5061             if (mController != null) {
5062                 // Find the first activity that is not finishing.
5063                 ActivityRecord next = r.getStack().topRunningActivityLocked(token, 0);
5064                 if (next != null) {
5065                     // ask watcher if this is allowed
5066                     boolean resumeOK = true;
5067                     try {
5068                         resumeOK = mController.activityResuming(next.packageName);
5069                     } catch (RemoteException e) {
5070                         mController = null;
5071                         Watchdog.getInstance().setActivityController(null);
5072                     }
5073
5074                     if (!resumeOK) {
5075                         Slog.i(TAG, "Not finishing activity because controller resumed");
5076                         return false;
5077                     }
5078                 }
5079             }
5080             final long origId = Binder.clearCallingIdentity();
5081             try {
5082                 boolean res;
5083                 final boolean finishWithRootActivity =
5084                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
5085                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
5086                         || (finishWithRootActivity && r == rootR)) {
5087                     // If requested, remove the task that is associated to this activity only if it
5088                     // was the root activity in the task. The result code and data is ignored
5089                     // because we don't support returning them across task boundaries. Also, to
5090                     // keep backwards compatibility we remove the task from recents when finishing
5091                     // task with root activity.
5092                     res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
5093                     if (!res) {
5094                         Slog.i(TAG, "Removing task failed to finish activity");
5095                     }
5096                 } else {
5097                     res = tr.getStack().requestFinishActivityLocked(token, resultCode,
5098                             resultData, "app-request", true);
5099                     if (!res) {
5100                         Slog.i(TAG, "Failed to finish by app-request");
5101                     }
5102                 }
5103                 return res;
5104             } finally {
5105                 Binder.restoreCallingIdentity(origId);
5106             }
5107         }
5108     }
5109
5110     @Override
5111     public final void finishHeavyWeightApp() {
5112         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5113                 != PackageManager.PERMISSION_GRANTED) {
5114             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
5115                     + Binder.getCallingPid()
5116                     + ", uid=" + Binder.getCallingUid()
5117                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5118             Slog.w(TAG, msg);
5119             throw new SecurityException(msg);
5120         }
5121
5122         synchronized(this) {
5123             if (mHeavyWeightProcess == null) {
5124                 return;
5125             }
5126
5127             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
5128             for (int i = 0; i < activities.size(); i++) {
5129                 ActivityRecord r = activities.get(i);
5130                 if (!r.finishing && r.isInStackLocked()) {
5131                     r.getStack().finishActivityLocked(r, Activity.RESULT_CANCELED,
5132                             null, "finish-heavy", true);
5133                 }
5134             }
5135
5136             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5137                     mHeavyWeightProcess.userId, 0));
5138             mHeavyWeightProcess = null;
5139         }
5140     }
5141
5142     @Override
5143     public void crashApplication(int uid, int initialPid, String packageName, int userId,
5144             String message) {
5145         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5146                 != PackageManager.PERMISSION_GRANTED) {
5147             String msg = "Permission Denial: crashApplication() from pid="
5148                     + Binder.getCallingPid()
5149                     + ", uid=" + Binder.getCallingUid()
5150                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5151             Slog.w(TAG, msg);
5152             throw new SecurityException(msg);
5153         }
5154
5155         synchronized(this) {
5156             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, userId, message);
5157         }
5158     }
5159
5160     @Override
5161     public final void finishSubActivity(IBinder token, String resultWho,
5162             int requestCode) {
5163         synchronized(this) {
5164             final long origId = Binder.clearCallingIdentity();
5165             ActivityRecord r = ActivityRecord.isInStackLocked(token);
5166             if (r != null) {
5167                 r.getStack().finishSubActivityLocked(r, resultWho, requestCode);
5168             }
5169             Binder.restoreCallingIdentity(origId);
5170         }
5171     }
5172
5173     @Override
5174     public boolean finishActivityAffinity(IBinder token) {
5175         synchronized(this) {
5176             final long origId = Binder.clearCallingIdentity();
5177             try {
5178                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5179                 if (r == null) {
5180                     return false;
5181                 }
5182
5183                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
5184                 // can finish.
5185                 final TaskRecord task = r.getTask();
5186                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
5187                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
5188                     mStackSupervisor.showLockTaskToast();
5189                     return false;
5190                 }
5191                 return task.getStack().finishActivityAffinityLocked(r);
5192             } finally {
5193                 Binder.restoreCallingIdentity(origId);
5194             }
5195         }
5196     }
5197
5198     @Override
5199     public void finishVoiceTask(IVoiceInteractionSession session) {
5200         synchronized (this) {
5201             final long origId = Binder.clearCallingIdentity();
5202             try {
5203                 // TODO: VI Consider treating local voice interactions and voice tasks
5204                 // differently here
5205                 mStackSupervisor.finishVoiceTask(session);
5206             } finally {
5207                 Binder.restoreCallingIdentity(origId);
5208             }
5209         }
5210
5211     }
5212
5213     @Override
5214     public boolean releaseActivityInstance(IBinder token) {
5215         synchronized(this) {
5216             final long origId = Binder.clearCallingIdentity();
5217             try {
5218                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5219                 if (r == null) {
5220                     return false;
5221                 }
5222                 return r.getStack().safelyDestroyActivityLocked(r, "app-req");
5223             } finally {
5224                 Binder.restoreCallingIdentity(origId);
5225             }
5226         }
5227     }
5228
5229     @Override
5230     public void releaseSomeActivities(IApplicationThread appInt) {
5231         synchronized(this) {
5232             final long origId = Binder.clearCallingIdentity();
5233             try {
5234                 ProcessRecord app = getRecordForAppLocked(appInt);
5235                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5236             } finally {
5237                 Binder.restoreCallingIdentity(origId);
5238             }
5239         }
5240     }
5241
5242     @Override
5243     public boolean willActivityBeVisible(IBinder token) {
5244         synchronized(this) {
5245             ActivityStack stack = ActivityRecord.getStackLocked(token);
5246             if (stack != null) {
5247                 return stack.willActivityBeVisibleLocked(token);
5248             }
5249             return false;
5250         }
5251     }
5252
5253     @Override
5254     public void overridePendingTransition(IBinder token, String packageName,
5255             int enterAnim, int exitAnim) {
5256         synchronized(this) {
5257             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5258             if (self == null) {
5259                 return;
5260             }
5261
5262             final long origId = Binder.clearCallingIdentity();
5263
5264             if (self.state == ActivityState.RESUMED
5265                     || self.state == ActivityState.PAUSING) {
5266                 mWindowManager.overridePendingAppTransition(packageName,
5267                         enterAnim, exitAnim, null);
5268             }
5269
5270             Binder.restoreCallingIdentity(origId);
5271         }
5272     }
5273
5274     /**
5275      * Main function for removing an existing process from the activity manager
5276      * as a result of that process going away.  Clears out all connections
5277      * to the process.
5278      */
5279     private final void handleAppDiedLocked(ProcessRecord app,
5280             boolean restarting, boolean allowRestart) {
5281         int pid = app.pid;
5282         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5283                 false /*replacingPid*/);
5284         if (!kept && !restarting) {
5285             removeLruProcessLocked(app);
5286             if (pid > 0) {
5287                 ProcessList.remove(pid);
5288             }
5289         }
5290
5291         if (mProfileProc == app) {
5292             clearProfilerLocked();
5293         }
5294
5295         // Remove this application's activities from active lists.
5296         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5297
5298         app.activities.clear();
5299
5300         if (app.instr != null) {
5301             Slog.w(TAG, "Crash of app " + app.processName
5302                   + " running instrumentation " + app.instr.mClass);
5303             Bundle info = new Bundle();
5304             info.putString("shortMsg", "Process crashed.");
5305             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5306         }
5307
5308         mWindowManager.deferSurfaceLayout();
5309         try {
5310             if (!restarting && hasVisibleActivities
5311                     && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5312                 // If there was nothing to resume, and we are not already restarting this process, but
5313                 // there is a visible activity that is hosted by the process...  then make sure all
5314                 // visible activities are running, taking care of restarting this process.
5315                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5316             }
5317         } finally {
5318             mWindowManager.continueSurfaceLayout();
5319         }
5320     }
5321
5322     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5323         final IBinder threadBinder = thread.asBinder();
5324         // Find the application record.
5325         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5326             final ProcessRecord rec = mLruProcesses.get(i);
5327             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5328                 return i;
5329             }
5330         }
5331         return -1;
5332     }
5333
5334     final ProcessRecord getRecordForAppLocked(
5335             IApplicationThread thread) {
5336         if (thread == null) {
5337             return null;
5338         }
5339
5340         int appIndex = getLRURecordIndexForAppLocked(thread);
5341         if (appIndex >= 0) {
5342             return mLruProcesses.get(appIndex);
5343         }
5344
5345         // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
5346         // double-check that.
5347         final IBinder threadBinder = thread.asBinder();
5348         final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5349         for (int i = pmap.size()-1; i >= 0; i--) {
5350             final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
5351             for (int j = procs.size()-1; j >= 0; j--) {
5352                 final ProcessRecord proc = procs.valueAt(j);
5353                 if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
5354                     Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
5355                             + proc);
5356                     return proc;
5357                 }
5358             }
5359         }
5360
5361         return null;
5362     }
5363
5364     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5365         // If there are no longer any background processes running,
5366         // and the app that died was not running instrumentation,
5367         // then tell everyone we are now low on memory.
5368         boolean haveBg = false;
5369         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5370             ProcessRecord rec = mLruProcesses.get(i);
5371             if (rec.thread != null
5372                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5373                 haveBg = true;
5374                 break;
5375             }
5376         }
5377
5378         if (!haveBg) {
5379             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5380             if (doReport) {
5381                 long now = SystemClock.uptimeMillis();
5382                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5383                     doReport = false;
5384                 } else {
5385                     mLastMemUsageReportTime = now;
5386                 }
5387             }
5388             final ArrayList<ProcessMemInfo> memInfos
5389                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5390             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5391             long now = SystemClock.uptimeMillis();
5392             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5393                 ProcessRecord rec = mLruProcesses.get(i);
5394                 if (rec == dyingProc || rec.thread == null) {
5395                     continue;
5396                 }
5397                 if (doReport) {
5398                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5399                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5400                 }
5401                 if ((rec.lastLowMemory+mConstants.GC_MIN_INTERVAL) <= now) {
5402                     // The low memory report is overriding any current
5403                     // state for a GC request.  Make sure to do
5404                     // heavy/important/visible/foreground processes first.
5405                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5406                         rec.lastRequestedGc = 0;
5407                     } else {
5408                         rec.lastRequestedGc = rec.lastLowMemory;
5409                     }
5410                     rec.reportLowMemory = true;
5411                     rec.lastLowMemory = now;
5412                     mProcessesToGc.remove(rec);
5413                     addProcessToGcListLocked(rec);
5414                 }
5415             }
5416             if (doReport) {
5417                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5418                 mHandler.sendMessage(msg);
5419             }
5420             scheduleAppGcsLocked();
5421         }
5422     }
5423
5424     final void appDiedLocked(ProcessRecord app) {
5425        appDiedLocked(app, app.pid, app.thread, false);
5426     }
5427
5428     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5429             boolean fromBinderDied) {
5430         // First check if this ProcessRecord is actually active for the pid.
5431         synchronized (mPidsSelfLocked) {
5432             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5433             if (curProc != app) {
5434                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5435                 return;
5436             }
5437         }
5438
5439         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5440         synchronized (stats) {
5441             stats.noteProcessDiedLocked(app.info.uid, pid);
5442         }
5443
5444         if (!app.killed) {
5445             if (!fromBinderDied) {
5446                 killProcessQuiet(pid);
5447             }
5448             killProcessGroup(app.uid, pid);
5449             app.killed = true;
5450         }
5451
5452         // Clean up already done if the process has been re-started.
5453         if (app.pid == pid && app.thread != null &&
5454                 app.thread.asBinder() == thread.asBinder()) {
5455             boolean doLowMem = app.instr == null;
5456             boolean doOomAdj = doLowMem;
5457             if (!app.killedByAm) {
5458                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
5459                         + ProcessList.makeOomAdjString(app.setAdj)
5460                         + ProcessList.makeProcStateString(app.setProcState));
5461                 mAllowLowerMemLevel = true;
5462             } else {
5463                 // Note that we always want to do oom adj to update our state with the
5464                 // new number of procs.
5465                 mAllowLowerMemLevel = false;
5466                 doLowMem = false;
5467             }
5468             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName,
5469                     app.setAdj, app.setProcState);
5470             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5471                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5472             handleAppDiedLocked(app, false, true);
5473
5474             if (doOomAdj) {
5475                 updateOomAdjLocked();
5476             }
5477             if (doLowMem) {
5478                 doLowMemReportIfNeededLocked(app);
5479             }
5480         } else if (app.pid != pid) {
5481             // A new process has already been started.
5482             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5483                     + ") has died and restarted (pid " + app.pid + ").");
5484             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5485         } else if (DEBUG_PROCESSES) {
5486             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5487                     + thread.asBinder());
5488         }
5489     }
5490
5491     /**
5492      * If a stack trace dump file is configured, dump process stack traces.
5493      * @param clearTraces causes the dump file to be erased prior to the new
5494      *    traces being written, if true; when false, the new traces will be
5495      *    appended to any existing file content.
5496      * @param firstPids of dalvik VM processes to dump stack traces for first
5497      * @param lastPids of dalvik VM processes to dump stack traces for last
5498      * @param nativePids optional list of native pids to dump stack crawls
5499      */
5500     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5501             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids,
5502             ArrayList<Integer> nativePids) {
5503         ArrayList<Integer> extraPids = null;
5504
5505         // Measure CPU usage as soon as we're called in order to get a realistic sampling
5506         // of the top users at the time of the request.
5507         if (processCpuTracker != null) {
5508             processCpuTracker.init();
5509             try {
5510                 Thread.sleep(200);
5511             } catch (InterruptedException ignored) {
5512             }
5513
5514             processCpuTracker.update();
5515
5516             // We'll take the stack crawls of just the top apps using CPU.
5517             final int N = processCpuTracker.countWorkingStats();
5518             extraPids = new ArrayList<>();
5519             for (int i = 0; i < N && extraPids.size() < 5; i++) {
5520                 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5521                 if (lastPids.indexOfKey(stats.pid) >= 0) {
5522                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
5523
5524                     extraPids.add(stats.pid);
5525                 } else if (DEBUG_ANR) {
5526                     Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5527                             + stats.pid);
5528                 }
5529             }
5530         }
5531
5532         boolean useTombstonedForJavaTraces = false;
5533         File tracesFile;
5534
5535         final String tracesDirProp = SystemProperties.get("dalvik.vm.stack-trace-dir", "");
5536         if (tracesDirProp.isEmpty()) {
5537             // When dalvik.vm.stack-trace-dir is not set, we are using the "old" trace
5538             // dumping scheme. All traces are written to a global trace file (usually
5539             // "/data/anr/traces.txt") so the code below must take care to unlink and recreate
5540             // the file if requested.
5541             //
5542             // This mode of operation will be removed in the near future.
5543
5544
5545             String globalTracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5546             if (globalTracesPath.isEmpty()) {
5547                 Slog.w(TAG, "dumpStackTraces: no trace path configured");
5548                 return null;
5549             }
5550
5551             tracesFile = new File(globalTracesPath);
5552             try {
5553                 if (clearTraces && tracesFile.exists()) {
5554                     tracesFile.delete();
5555                 }
5556
5557                 tracesFile.createNewFile();
5558                 FileUtils.setPermissions(globalTracesPath, 0666, -1, -1); // -rw-rw-rw-
5559             } catch (IOException e) {
5560                 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesFile, e);
5561                 return null;
5562             }
5563         } else {
5564             File tracesDir = new File(tracesDirProp);
5565             // When dalvik.vm.stack-trace-dir is set, we use the "new" trace dumping scheme.
5566             // Each set of ANR traces is written to a separate file and dumpstate will process
5567             // all such files and add them to a captured bug report if they're recent enough.
5568             maybePruneOldTraces(tracesDir);
5569
5570             // NOTE: We should consider creating the file in native code atomically once we've
5571             // gotten rid of the old scheme of dumping and lot of the code that deals with paths
5572             // can be removed.
5573             tracesFile = createAnrDumpFile(tracesDir);
5574             if (tracesFile == null) {
5575                 return null;
5576             }
5577
5578             useTombstonedForJavaTraces = true;
5579         }
5580
5581         dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids,
5582                 useTombstonedForJavaTraces);
5583         return tracesFile;
5584     }
5585
5586     @GuardedBy("ActivityManagerService.class")
5587     private static SimpleDateFormat sAnrFileDateFormat;
5588
5589     private static synchronized File createAnrDumpFile(File tracesDir) {
5590         if (sAnrFileDateFormat == null) {
5591             sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
5592         }
5593
5594         final String formattedDate = sAnrFileDateFormat.format(new Date());
5595         final File anrFile = new File(tracesDir, "anr_" + formattedDate);
5596
5597         try {
5598             if (anrFile.createNewFile()) {
5599                 FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
5600                 return anrFile;
5601             } else {
5602                 Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
5603             }
5604         } catch (IOException ioe) {
5605             Slog.w(TAG, "Exception creating ANR dump file:", ioe);
5606         }
5607
5608         return null;
5609     }
5610
5611     /**
5612      * Prune all trace files that are more than a day old.
5613      *
5614      * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
5615      * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
5616      * since it's the system_server that creates trace files for most ANRs.
5617      */
5618     private static void maybePruneOldTraces(File tracesDir) {
5619         final long now = System.currentTimeMillis();
5620         final File[] traceFiles = tracesDir.listFiles();
5621
5622         if (traceFiles != null) {
5623             for (File file : traceFiles) {
5624                 if ((now - file.lastModified()) > DAY_IN_MILLIS)  {
5625                     if (!file.delete()) {
5626                         Slog.w(TAG, "Unable to prune stale trace file: " + file);
5627                     }
5628                 }
5629             }
5630         }
5631     }
5632
5633     /**
5634      * Legacy code, do not use. Existing users will be deleted.
5635      *
5636      * @deprecated
5637      */
5638     @Deprecated
5639     public static class DumpStackFileObserver extends FileObserver {
5640         // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
5641         private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
5642
5643         private final String mTracesPath;
5644         private boolean mClosed;
5645
5646         public DumpStackFileObserver(String tracesPath) {
5647             super(tracesPath, FileObserver.CLOSE_WRITE);
5648             mTracesPath = tracesPath;
5649         }
5650
5651         @Override
5652         public synchronized void onEvent(int event, String path) {
5653             mClosed = true;
5654             notify();
5655         }
5656
5657         public long dumpWithTimeout(int pid, long timeout) {
5658             sendSignal(pid, SIGNAL_QUIT);
5659             final long start = SystemClock.elapsedRealtime();
5660
5661             final long waitTime = Math.min(timeout, TRACE_DUMP_TIMEOUT_MS);
5662             synchronized (this) {
5663                 try {
5664                     wait(waitTime); // Wait for traces file to be closed.
5665                 } catch (InterruptedException e) {
5666                     Slog.wtf(TAG, e);
5667                 }
5668             }
5669
5670             // This avoids a corner case of passing a negative time to the native
5671             // trace in case we've already hit the overall timeout.
5672             final long timeWaited = SystemClock.elapsedRealtime() - start;
5673             if (timeWaited >= timeout) {
5674                 return timeWaited;
5675             }
5676
5677             if (!mClosed) {
5678                 Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
5679                        ". Attempting native stack collection.");
5680
5681                 final long nativeDumpTimeoutMs = Math.min(
5682                         NATIVE_DUMP_TIMEOUT_MS, timeout - timeWaited);
5683
5684                 Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath,
5685                         (int) (nativeDumpTimeoutMs / 1000));
5686             }
5687
5688             final long end = SystemClock.elapsedRealtime();
5689             mClosed = false;
5690
5691             return (end - start);
5692         }
5693     }
5694
5695     /**
5696      * Dump java traces for process {@code pid} to the specified file. If java trace dumping
5697      * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
5698      * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
5699      * attempting to obtain native traces in the case of a failure. Returns the total time spent
5700      * capturing traces.
5701      */
5702     private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
5703         final long timeStart = SystemClock.elapsedRealtime();
5704         if (!Debug.dumpJavaBacktraceToFileTimeout(pid, fileName, (int) (timeoutMs / 1000))) {
5705             Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
5706                     (NATIVE_DUMP_TIMEOUT_MS / 1000));
5707         }
5708
5709         return SystemClock.elapsedRealtime() - timeStart;
5710     }
5711
5712     private static void dumpStackTraces(String tracesFile, ArrayList<Integer> firstPids,
5713             ArrayList<Integer> nativePids, ArrayList<Integer> extraPids,
5714             boolean useTombstonedForJavaTraces) {
5715
5716         // We don't need any sort of inotify based monitoring when we're dumping traces via
5717         // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
5718         // control of all writes to the file in question.
5719         final DumpStackFileObserver observer;
5720         if (useTombstonedForJavaTraces) {
5721             observer = null;
5722         } else {
5723             // Use a FileObserver to detect when traces finish writing.
5724             // The order of traces is considered important to maintain for legibility.
5725             observer = new DumpStackFileObserver(tracesFile);
5726         }
5727
5728         // We must complete all stack dumps within 20 seconds.
5729         long remainingTime = 20 * 1000;
5730         try {
5731             if (observer != null) {
5732                 observer.startWatching();
5733             }
5734
5735             // First collect all of the stacks of the most important pids.
5736             if (firstPids != null) {
5737                 int num = firstPids.size();
5738                 for (int i = 0; i < num; i++) {
5739                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5740                             + firstPids.get(i));
5741                     final long timeTaken;
5742                     if (useTombstonedForJavaTraces) {
5743                         timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
5744                     } else {
5745                         timeTaken = observer.dumpWithTimeout(firstPids.get(i), remainingTime);
5746                     }
5747
5748                     remainingTime -= timeTaken;
5749                     if (remainingTime <= 0) {
5750                         Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + firstPids.get(i) +
5751                             "); deadline exceeded.");
5752                         return;
5753                     }
5754
5755                     if (DEBUG_ANR) {
5756                         Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
5757                     }
5758                 }
5759             }
5760
5761             // Next collect the stacks of the native pids
5762             if (nativePids != null) {
5763                 for (int pid : nativePids) {
5764                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5765                     final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
5766
5767                     final long start = SystemClock.elapsedRealtime();
5768                     Debug.dumpNativeBacktraceToFileTimeout(
5769                             pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
5770                     final long timeTaken = SystemClock.elapsedRealtime() - start;
5771
5772                     remainingTime -= timeTaken;
5773                     if (remainingTime <= 0) {
5774                         Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
5775                             "); deadline exceeded.");
5776                         return;
5777                     }
5778
5779                     if (DEBUG_ANR) {
5780                         Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
5781                     }
5782                 }
5783             }
5784
5785             // Lastly, dump stacks for all extra PIDs from the CPU tracker.
5786             if (extraPids != null) {
5787                 for (int pid : extraPids) {
5788                     if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid " + pid);
5789
5790                     final long timeTaken;
5791                     if (useTombstonedForJavaTraces) {
5792                         timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
5793                     } else {
5794                         timeTaken = observer.dumpWithTimeout(pid, remainingTime);
5795                     }
5796
5797                     remainingTime -= timeTaken;
5798                     if (remainingTime <= 0) {
5799                         Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
5800                                 "); deadline exceeded.");
5801                         return;
5802                     }
5803
5804                     if (DEBUG_ANR) {
5805                         Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
5806                     }
5807                 }
5808             }
5809         } finally {
5810             if (observer != null) {
5811                 observer.stopWatching();
5812             }
5813         }
5814     }
5815
5816     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5817         if (true || Build.IS_USER) {
5818             return;
5819         }
5820         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5821         if (tracesPath == null || tracesPath.length() == 0) {
5822             return;
5823         }
5824
5825         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5826         StrictMode.allowThreadDiskWrites();
5827         try {
5828             final File tracesFile = new File(tracesPath);
5829             final File tracesDir = tracesFile.getParentFile();
5830             final File tracesTmp = new File(tracesDir, "__tmp__");
5831             try {
5832                 if (tracesFile.exists()) {
5833                     tracesTmp.delete();
5834                     tracesFile.renameTo(tracesTmp);
5835                 }
5836                 StringBuilder sb = new StringBuilder();
5837                 Time tobj = new Time();
5838                 tobj.set(System.currentTimeMillis());
5839                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5840                 sb.append(": ");
5841                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5842                 sb.append(" since ");
5843                 sb.append(msg);
5844                 FileOutputStream fos = new FileOutputStream(tracesFile);
5845                 fos.write(sb.toString().getBytes());
5846                 if (app == null) {
5847                     fos.write("\n*** No application process!".getBytes());
5848                 }
5849                 fos.close();
5850                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5851             } catch (IOException e) {
5852                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5853                 return;
5854             }
5855
5856             if (app != null) {
5857                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5858                 firstPids.add(app.pid);
5859                 dumpStackTraces(tracesPath, firstPids, null, null, true /* useTombstoned */);
5860             }
5861
5862             File lastTracesFile = null;
5863             File curTracesFile = null;
5864             for (int i=9; i>=0; i--) {
5865                 String name = String.format(Locale.US, "slow%02d.txt", i);
5866                 curTracesFile = new File(tracesDir, name);
5867                 if (curTracesFile.exists()) {
5868                     if (lastTracesFile != null) {
5869                         curTracesFile.renameTo(lastTracesFile);
5870                     } else {
5871                         curTracesFile.delete();
5872                     }
5873                 }
5874                 lastTracesFile = curTracesFile;
5875             }
5876             tracesFile.renameTo(curTracesFile);
5877             if (tracesTmp.exists()) {
5878                 tracesTmp.renameTo(tracesFile);
5879             }
5880         } finally {
5881             StrictMode.setThreadPolicy(oldPolicy);
5882         }
5883     }
5884
5885     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5886         if (!mLaunchWarningShown) {
5887             mLaunchWarningShown = true;
5888             mUiHandler.post(new Runnable() {
5889                 @Override
5890                 public void run() {
5891                     synchronized (ActivityManagerService.this) {
5892                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5893                         d.show();
5894                         mUiHandler.postDelayed(new Runnable() {
5895                             @Override
5896                             public void run() {
5897                                 synchronized (ActivityManagerService.this) {
5898                                     d.dismiss();
5899                                     mLaunchWarningShown = false;
5900                                 }
5901                             }
5902                         }, 4000);
5903                     }
5904                 }
5905             });
5906         }
5907     }
5908
5909     @Override
5910     public boolean clearApplicationUserData(final String packageName,
5911             final IPackageDataObserver observer, int userId) {
5912         enforceNotIsolatedCaller("clearApplicationUserData");
5913         int uid = Binder.getCallingUid();
5914         int pid = Binder.getCallingPid();
5915         final int resolvedUserId = mUserController.handleIncomingUser(pid, uid, userId, false,
5916                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5917
5918         final ApplicationInfo appInfo;
5919         final boolean isInstantApp;
5920
5921         long callingId = Binder.clearCallingIdentity();
5922         try {
5923             IPackageManager pm = AppGlobals.getPackageManager();
5924             synchronized(this) {
5925                 // Instant packages are not protected
5926                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5927                         resolvedUserId, packageName)) {
5928                     throw new SecurityException(
5929                             "Cannot clear data for a protected package: " + packageName);
5930                 }
5931
5932                 ApplicationInfo applicationInfo = null;
5933                 try {
5934                     applicationInfo = pm.getApplicationInfo(packageName,
5935                             MATCH_UNINSTALLED_PACKAGES, resolvedUserId);
5936                 } catch (RemoteException e) {
5937                     /* ignore */
5938                 }
5939                 appInfo = applicationInfo;
5940
5941                 final boolean clearingOwnUidData = appInfo != null && appInfo.uid == uid;
5942
5943                 if (!clearingOwnUidData && checkComponentPermission(permission.CLEAR_APP_USER_DATA,
5944                         pid, uid, -1, true) != PackageManager.PERMISSION_GRANTED) {
5945                     throw new SecurityException("PID " + pid + " does not have permission "
5946                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5947                             + " of package " + packageName);
5948                 }
5949
5950                 final boolean hasInstantMetadata = getPackageManagerInternalLocked()
5951                         .hasInstantApplicationMetadata(packageName, resolvedUserId);
5952                 final boolean isUninstalledAppWithoutInstantMetadata =
5953                         (appInfo == null && !hasInstantMetadata);
5954                 isInstantApp = (appInfo != null && appInfo.isInstantApp())
5955                         || hasInstantMetadata;
5956                 final boolean canAccessInstantApps = checkComponentPermission(
5957                         permission.ACCESS_INSTANT_APPS, pid, uid, -1, true)
5958                         == PackageManager.PERMISSION_GRANTED;
5959
5960                 if (isUninstalledAppWithoutInstantMetadata || (isInstantApp
5961                         && !canAccessInstantApps)) {
5962                     Slog.w(TAG, "Invalid packageName: " + packageName);
5963                     if (observer != null) {
5964                         try {
5965                             observer.onRemoveCompleted(packageName, false);
5966                         } catch (RemoteException e) {
5967                             Slog.i(TAG, "Observer no longer exists.");
5968                         }
5969                     }
5970                     return false;
5971                 }
5972
5973                 if (appInfo != null) {
5974                     forceStopPackageLocked(packageName, appInfo.uid, "clear data");
5975                     // Remove all tasks match the cleared application package and user
5976                     for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5977                         final TaskRecord tr = mRecentTasks.get(i);
5978                         final String taskPackageName =
5979                                 tr.getBaseIntent().getComponent().getPackageName();
5980                         if (tr.userId != resolvedUserId) continue;
5981                         if (!taskPackageName.equals(packageName)) continue;
5982                         mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
5983                                 REMOVE_FROM_RECENTS);
5984                     }
5985                 }
5986             }
5987
5988             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5989                 @Override
5990                 public void onRemoveCompleted(String packageName, boolean succeeded)
5991                         throws RemoteException {
5992                     if (appInfo != null) {
5993                         synchronized (ActivityManagerService.this) {
5994                             finishForceStopPackageLocked(packageName, appInfo.uid);
5995                         }
5996                     }
5997                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5998                             Uri.fromParts("package", packageName, null));
5999                     intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
6000                     intent.putExtra(Intent.EXTRA_UID, (appInfo != null) ? appInfo.uid : -1);
6001                     intent.putExtra(Intent.EXTRA_USER_HANDLE, resolvedUserId);
6002                     if (isInstantApp) {
6003                         intent.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
6004                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6005                                 null, null, permission.ACCESS_INSTANT_APPS, null, false, false,
6006                                 resolvedUserId);
6007                     } else {
6008                         broadcastIntentInPackage("android", SYSTEM_UID, intent, null, null, 0,
6009                                 null, null, null, null, false, false, resolvedUserId);
6010                     }
6011
6012                     if (observer != null) {
6013                         observer.onRemoveCompleted(packageName, succeeded);
6014                     }
6015                 }
6016             };
6017
6018             try {
6019                 // Clear application user data
6020                 pm.clearApplicationUserData(packageName, localObserver, resolvedUserId);
6021
6022                 if (appInfo != null) {
6023                     synchronized (this) {
6024                         // Remove all permissions granted from/to this package
6025                         removeUriPermissionsForPackageLocked(packageName, resolvedUserId, true);
6026                     }
6027
6028                     // Reset notification settings.
6029                     INotificationManager inm = NotificationManager.getService();
6030                     inm.clearData(packageName, appInfo.uid, uid == appInfo.uid);
6031                 }
6032             } catch (RemoteException e) {
6033             }
6034         } finally {
6035             Binder.restoreCallingIdentity(callingId);
6036         }
6037         return true;
6038     }
6039
6040     @Override
6041     public void killBackgroundProcesses(final String packageName, int userId) {
6042         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6043                 != PackageManager.PERMISSION_GRANTED &&
6044                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
6045                         != PackageManager.PERMISSION_GRANTED) {
6046             String msg = "Permission Denial: killBackgroundProcesses() from pid="
6047                     + Binder.getCallingPid()
6048                     + ", uid=" + Binder.getCallingUid()
6049                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6050             Slog.w(TAG, msg);
6051             throw new SecurityException(msg);
6052         }
6053
6054         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6055                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
6056         long callingId = Binder.clearCallingIdentity();
6057         try {
6058             IPackageManager pm = AppGlobals.getPackageManager();
6059             synchronized(this) {
6060                 int appId = -1;
6061                 try {
6062                     appId = UserHandle.getAppId(
6063                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6064                 } catch (RemoteException e) {
6065                 }
6066                 if (appId == -1) {
6067                     Slog.w(TAG, "Invalid packageName: " + packageName);
6068                     return;
6069                 }
6070                 killPackageProcessesLocked(packageName, appId, userId,
6071                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
6072             }
6073         } finally {
6074             Binder.restoreCallingIdentity(callingId);
6075         }
6076     }
6077
6078     @Override
6079     public void killAllBackgroundProcesses() {
6080         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6081                 != PackageManager.PERMISSION_GRANTED) {
6082             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
6083                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6084                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6085             Slog.w(TAG, msg);
6086             throw new SecurityException(msg);
6087         }
6088
6089         final long callingId = Binder.clearCallingIdentity();
6090         try {
6091             synchronized (this) {
6092                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6093                 final int NP = mProcessNames.getMap().size();
6094                 for (int ip = 0; ip < NP; ip++) {
6095                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6096                     final int NA = apps.size();
6097                     for (int ia = 0; ia < NA; ia++) {
6098                         final ProcessRecord app = apps.valueAt(ia);
6099                         if (app.persistent) {
6100                             // We don't kill persistent processes.
6101                             continue;
6102                         }
6103                         if (app.removed) {
6104                             procs.add(app);
6105                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
6106                             app.removed = true;
6107                             procs.add(app);
6108                         }
6109                     }
6110                 }
6111
6112                 final int N = procs.size();
6113                 for (int i = 0; i < N; i++) {
6114                     removeProcessLocked(procs.get(i), false, true, "kill all background");
6115                 }
6116
6117                 mAllowLowerMemLevel = true;
6118
6119                 updateOomAdjLocked();
6120                 doLowMemReportIfNeededLocked(null);
6121             }
6122         } finally {
6123             Binder.restoreCallingIdentity(callingId);
6124         }
6125     }
6126
6127     /**
6128      * Kills all background processes, except those matching any of the
6129      * specified properties.
6130      *
6131      * @param minTargetSdk the target SDK version at or above which to preserve
6132      *                     processes, or {@code -1} to ignore the target SDK
6133      * @param maxProcState the process state at or below which to preserve
6134      *                     processes, or {@code -1} to ignore the process state
6135      */
6136     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
6137         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
6138                 != PackageManager.PERMISSION_GRANTED) {
6139             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
6140                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
6141                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
6142             Slog.w(TAG, msg);
6143             throw new SecurityException(msg);
6144         }
6145
6146         final long callingId = Binder.clearCallingIdentity();
6147         try {
6148             synchronized (this) {
6149                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
6150                 final int NP = mProcessNames.getMap().size();
6151                 for (int ip = 0; ip < NP; ip++) {
6152                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6153                     final int NA = apps.size();
6154                     for (int ia = 0; ia < NA; ia++) {
6155                         final ProcessRecord app = apps.valueAt(ia);
6156                         if (app.removed) {
6157                             procs.add(app);
6158                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
6159                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
6160                             app.removed = true;
6161                             procs.add(app);
6162                         }
6163                     }
6164                 }
6165
6166                 final int N = procs.size();
6167                 for (int i = 0; i < N; i++) {
6168                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
6169                 }
6170             }
6171         } finally {
6172             Binder.restoreCallingIdentity(callingId);
6173         }
6174     }
6175
6176     @Override
6177     public void forceStopPackage(final String packageName, int userId) {
6178         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
6179                 != PackageManager.PERMISSION_GRANTED) {
6180             String msg = "Permission Denial: forceStopPackage() from pid="
6181                     + Binder.getCallingPid()
6182                     + ", uid=" + Binder.getCallingUid()
6183                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
6184             Slog.w(TAG, msg);
6185             throw new SecurityException(msg);
6186         }
6187         final int callingPid = Binder.getCallingPid();
6188         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
6189                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
6190         long callingId = Binder.clearCallingIdentity();
6191         try {
6192             IPackageManager pm = AppGlobals.getPackageManager();
6193             synchronized(this) {
6194                 int[] users = userId == UserHandle.USER_ALL
6195                         ? mUserController.getUsers() : new int[] { userId };
6196                 for (int user : users) {
6197                     int pkgUid = -1;
6198                     try {
6199                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
6200                                 user);
6201                     } catch (RemoteException e) {
6202                     }
6203                     if (pkgUid == -1) {
6204                         Slog.w(TAG, "Invalid packageName: " + packageName);
6205                         continue;
6206                     }
6207                     try {
6208                         pm.setPackageStoppedState(packageName, true, user);
6209                     } catch (RemoteException e) {
6210                     } catch (IllegalArgumentException e) {
6211                         Slog.w(TAG, "Failed trying to unstop package "
6212                                 + packageName + ": " + e);
6213                     }
6214                     if (mUserController.isUserRunningLocked(user, 0)) {
6215                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
6216                         finishForceStopPackageLocked(packageName, pkgUid);
6217                     }
6218                 }
6219             }
6220         } finally {
6221             Binder.restoreCallingIdentity(callingId);
6222         }
6223     }
6224
6225     @Override
6226     public void addPackageDependency(String packageName) {
6227         synchronized (this) {
6228             int callingPid = Binder.getCallingPid();
6229             if (callingPid == myPid()) {
6230                 //  Yeah, um, no.
6231                 return;
6232             }
6233             ProcessRecord proc;
6234             synchronized (mPidsSelfLocked) {
6235                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
6236             }
6237             if (proc != null) {
6238                 if (proc.pkgDeps == null) {
6239                     proc.pkgDeps = new ArraySet<String>(1);
6240                 }
6241                 proc.pkgDeps.add(packageName);
6242             }
6243         }
6244     }
6245
6246     /*
6247      * The pkg name and app id have to be specified.
6248      */
6249     @Override
6250     public void killApplication(String pkg, int appId, int userId, String reason) {
6251         if (pkg == null) {
6252             return;
6253         }
6254         // Make sure the uid is valid.
6255         if (appId < 0) {
6256             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
6257             return;
6258         }
6259         int callerUid = Binder.getCallingUid();
6260         // Only the system server can kill an application
6261         if (UserHandle.getAppId(callerUid) == SYSTEM_UID) {
6262             // Post an aysnc message to kill the application
6263             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
6264             msg.arg1 = appId;
6265             msg.arg2 = userId;
6266             Bundle bundle = new Bundle();
6267             bundle.putString("pkg", pkg);
6268             bundle.putString("reason", reason);
6269             msg.obj = bundle;
6270             mHandler.sendMessage(msg);
6271         } else {
6272             throw new SecurityException(callerUid + " cannot kill pkg: " +
6273                     pkg);
6274         }
6275     }
6276
6277     @Override
6278     public void closeSystemDialogs(String reason) {
6279         enforceNotIsolatedCaller("closeSystemDialogs");
6280
6281         final int pid = Binder.getCallingPid();
6282         final int uid = Binder.getCallingUid();
6283         final long origId = Binder.clearCallingIdentity();
6284         try {
6285             synchronized (this) {
6286                 // Only allow this from foreground processes, so that background
6287                 // applications can't abuse it to prevent system UI from being shown.
6288                 if (uid >= FIRST_APPLICATION_UID) {
6289                     ProcessRecord proc;
6290                     synchronized (mPidsSelfLocked) {
6291                         proc = mPidsSelfLocked.get(pid);
6292                     }
6293                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
6294                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
6295                                 + " from background process " + proc);
6296                         return;
6297                     }
6298                 }
6299                 closeSystemDialogsLocked(reason);
6300             }
6301         } finally {
6302             Binder.restoreCallingIdentity(origId);
6303         }
6304     }
6305
6306     void closeSystemDialogsLocked(String reason) {
6307         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
6308         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6309                 | Intent.FLAG_RECEIVER_FOREGROUND);
6310         if (reason != null) {
6311             intent.putExtra("reason", reason);
6312         }
6313         mWindowManager.closeSystemDialogs(reason);
6314
6315         mStackSupervisor.closeSystemDialogsLocked();
6316
6317         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
6318                 AppOpsManager.OP_NONE, null, false, false,
6319                 -1, SYSTEM_UID, UserHandle.USER_ALL);
6320     }
6321
6322     @Override
6323     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
6324         enforceNotIsolatedCaller("getProcessMemoryInfo");
6325         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
6326         for (int i=pids.length-1; i>=0; i--) {
6327             ProcessRecord proc;
6328             int oomAdj;
6329             synchronized (this) {
6330                 synchronized (mPidsSelfLocked) {
6331                     proc = mPidsSelfLocked.get(pids[i]);
6332                     oomAdj = proc != null ? proc.setAdj : 0;
6333                 }
6334             }
6335             infos[i] = new Debug.MemoryInfo();
6336             Debug.getMemoryInfo(pids[i], infos[i]);
6337             if (proc != null) {
6338                 synchronized (this) {
6339                     if (proc.thread != null && proc.setAdj == oomAdj) {
6340                         // Record this for posterity if the process has been stable.
6341                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
6342                                 infos[i].getTotalUss(), false, proc.pkgList);
6343                     }
6344                 }
6345             }
6346         }
6347         return infos;
6348     }
6349
6350     @Override
6351     public long[] getProcessPss(int[] pids) {
6352         enforceNotIsolatedCaller("getProcessPss");
6353         long[] pss = new long[pids.length];
6354         for (int i=pids.length-1; i>=0; i--) {
6355             ProcessRecord proc;
6356             int oomAdj;
6357             synchronized (this) {
6358                 synchronized (mPidsSelfLocked) {
6359                     proc = mPidsSelfLocked.get(pids[i]);
6360                     oomAdj = proc != null ? proc.setAdj : 0;
6361                 }
6362             }
6363             long[] tmpUss = new long[1];
6364             pss[i] = Debug.getPss(pids[i], tmpUss, null);
6365             if (proc != null) {
6366                 synchronized (this) {
6367                     if (proc.thread != null && proc.setAdj == oomAdj) {
6368                         // Record this for posterity if the process has been stable.
6369                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
6370                     }
6371                 }
6372             }
6373         }
6374         return pss;
6375     }
6376
6377     @Override
6378     public void killApplicationProcess(String processName, int uid) {
6379         if (processName == null) {
6380             return;
6381         }
6382
6383         int callerUid = Binder.getCallingUid();
6384         // Only the system server can kill an application
6385         if (callerUid == SYSTEM_UID) {
6386             synchronized (this) {
6387                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
6388                 if (app != null && app.thread != null) {
6389                     try {
6390                         app.thread.scheduleSuicide();
6391                     } catch (RemoteException e) {
6392                         // If the other end already died, then our work here is done.
6393                     }
6394                 } else {
6395                     Slog.w(TAG, "Process/uid not found attempting kill of "
6396                             + processName + " / " + uid);
6397                 }
6398             }
6399         } else {
6400             throw new SecurityException(callerUid + " cannot kill app process: " +
6401                     processName);
6402         }
6403     }
6404
6405     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
6406         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
6407                 false, true, false, false, UserHandle.getUserId(uid), reason);
6408     }
6409
6410     private void finishForceStopPackageLocked(final String packageName, int uid) {
6411         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
6412                 Uri.fromParts("package", packageName, null));
6413         if (!mProcessesReady) {
6414             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
6415                     | Intent.FLAG_RECEIVER_FOREGROUND);
6416         }
6417         intent.putExtra(Intent.EXTRA_UID, uid);
6418         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
6419         broadcastIntentLocked(null, null, intent,
6420                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
6421                 null, false, false, MY_PID, SYSTEM_UID, UserHandle.getUserId(uid));
6422     }
6423
6424
6425     private final boolean killPackageProcessesLocked(String packageName, int appId,
6426             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
6427             boolean doit, boolean evenPersistent, String reason) {
6428         ArrayList<ProcessRecord> procs = new ArrayList<>();
6429
6430         // Remove all processes this package may have touched: all with the
6431         // same UID (except for the system or root user), and all whose name
6432         // matches the package name.
6433         final int NP = mProcessNames.getMap().size();
6434         for (int ip=0; ip<NP; ip++) {
6435             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
6436             final int NA = apps.size();
6437             for (int ia=0; ia<NA; ia++) {
6438                 ProcessRecord app = apps.valueAt(ia);
6439                 if (app.persistent && !evenPersistent) {
6440                     // we don't kill persistent processes
6441                     continue;
6442                 }
6443                 if (app.removed) {
6444                     if (doit) {
6445                         procs.add(app);
6446                     }
6447                     continue;
6448                 }
6449
6450                 // Skip process if it doesn't meet our oom adj requirement.
6451                 if (app.setAdj < minOomAdj) {
6452                     continue;
6453                 }
6454
6455                 // If no package is specified, we call all processes under the
6456                 // give user id.
6457                 if (packageName == null) {
6458                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6459                         continue;
6460                     }
6461                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6462                         continue;
6463                     }
6464                 // Package has been specified, we want to hit all processes
6465                 // that match it.  We need to qualify this by the processes
6466                 // that are running under the specified app and user ID.
6467                 } else {
6468                     final boolean isDep = app.pkgDeps != null
6469                             && app.pkgDeps.contains(packageName);
6470                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6471                         continue;
6472                     }
6473                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6474                         continue;
6475                     }
6476                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6477                         continue;
6478                     }
6479                 }
6480
6481                 // Process has passed all conditions, kill it!
6482                 if (!doit) {
6483                     return true;
6484                 }
6485                 app.removed = true;
6486                 procs.add(app);
6487             }
6488         }
6489
6490         int N = procs.size();
6491         for (int i=0; i<N; i++) {
6492             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6493         }
6494         updateOomAdjLocked();
6495         return N > 0;
6496     }
6497
6498     private void cleanupDisabledPackageComponentsLocked(
6499             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6500
6501         Set<String> disabledClasses = null;
6502         boolean packageDisabled = false;
6503         IPackageManager pm = AppGlobals.getPackageManager();
6504
6505         if (changedClasses == null) {
6506             // Nothing changed...
6507             return;
6508         }
6509
6510         // Determine enable/disable state of the package and its components.
6511         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6512         for (int i = changedClasses.length - 1; i >= 0; i--) {
6513             final String changedClass = changedClasses[i];
6514
6515             if (changedClass.equals(packageName)) {
6516                 try {
6517                     // Entire package setting changed
6518                     enabled = pm.getApplicationEnabledSetting(packageName,
6519                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6520                 } catch (Exception e) {
6521                     // No such package/component; probably racing with uninstall.  In any
6522                     // event it means we have nothing further to do here.
6523                     return;
6524                 }
6525                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6526                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6527                 if (packageDisabled) {
6528                     // Entire package is disabled.
6529                     // No need to continue to check component states.
6530                     disabledClasses = null;
6531                     break;
6532                 }
6533             } else {
6534                 try {
6535                     enabled = pm.getComponentEnabledSetting(
6536                             new ComponentName(packageName, changedClass),
6537                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6538                 } catch (Exception e) {
6539                     // As above, probably racing with uninstall.
6540                     return;
6541                 }
6542                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6543                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6544                     if (disabledClasses == null) {
6545                         disabledClasses = new ArraySet<>(changedClasses.length);
6546                     }
6547                     disabledClasses.add(changedClass);
6548                 }
6549             }
6550         }
6551
6552         if (!packageDisabled && disabledClasses == null) {
6553             // Nothing to do here...
6554             return;
6555         }
6556
6557         // Clean-up disabled activities.
6558         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6559                 packageName, disabledClasses, true, false, userId) && mBooted) {
6560             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6561             mStackSupervisor.scheduleIdleLocked();
6562         }
6563
6564         // Clean-up disabled tasks
6565         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6566
6567         // Clean-up disabled services.
6568         mServices.bringDownDisabledPackageServicesLocked(
6569                 packageName, disabledClasses, userId, false, killProcess, true);
6570
6571         // Clean-up disabled providers.
6572         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6573         mProviderMap.collectPackageProvidersLocked(
6574                 packageName, disabledClasses, true, false, userId, providers);
6575         for (int i = providers.size() - 1; i >= 0; i--) {
6576             removeDyingProviderLocked(null, providers.get(i), true);
6577         }
6578
6579         // Clean-up disabled broadcast receivers.
6580         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6581             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6582                     packageName, disabledClasses, userId, true);
6583         }
6584
6585     }
6586
6587     final boolean clearBroadcastQueueForUserLocked(int userId) {
6588         boolean didSomething = false;
6589         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6590             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6591                     null, null, userId, true);
6592         }
6593         return didSomething;
6594     }
6595
6596     final boolean forceStopPackageLocked(String packageName, int appId,
6597             boolean callerWillRestart, boolean purgeCache, boolean doit,
6598             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6599         int i;
6600
6601         if (userId == UserHandle.USER_ALL && packageName == null) {
6602             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6603         }
6604
6605         if (appId < 0 && packageName != null) {
6606             try {
6607                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6608                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6609             } catch (RemoteException e) {
6610             }
6611         }
6612
6613         if (doit) {
6614             if (packageName != null) {
6615                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6616                         + " user=" + userId + ": " + reason);
6617             } else {
6618                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6619             }
6620
6621             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6622         }
6623
6624         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6625                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6626                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6627
6628         didSomething |= mActivityStarter.clearPendingActivityLaunchesLocked(packageName);
6629
6630         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6631                 packageName, null, doit, evenPersistent, userId)) {
6632             if (!doit) {
6633                 return true;
6634             }
6635             didSomething = true;
6636         }
6637
6638         if (mServices.bringDownDisabledPackageServicesLocked(
6639                 packageName, null, userId, evenPersistent, true, doit)) {
6640             if (!doit) {
6641                 return true;
6642             }
6643             didSomething = true;
6644         }
6645
6646         if (packageName == null) {
6647             // Remove all sticky broadcasts from this user.
6648             mStickyBroadcasts.remove(userId);
6649         }
6650
6651         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6652         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6653                 userId, providers)) {
6654             if (!doit) {
6655                 return true;
6656             }
6657             didSomething = true;
6658         }
6659         for (i = providers.size() - 1; i >= 0; i--) {
6660             removeDyingProviderLocked(null, providers.get(i), true);
6661         }
6662
6663         // Remove transient permissions granted from/to this package/user
6664         removeUriPermissionsForPackageLocked(packageName, userId, false);
6665
6666         if (doit) {
6667             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6668                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6669                         packageName, null, userId, doit);
6670             }
6671         }
6672
6673         if (packageName == null || uninstalling) {
6674             // Remove pending intents.  For now we only do this when force
6675             // stopping users, because we have some problems when doing this
6676             // for packages -- app widgets are not currently cleaned up for
6677             // such packages, so they can be left with bad pending intents.
6678             if (mIntentSenderRecords.size() > 0) {
6679                 Iterator<WeakReference<PendingIntentRecord>> it
6680                         = mIntentSenderRecords.values().iterator();
6681                 while (it.hasNext()) {
6682                     WeakReference<PendingIntentRecord> wpir = it.next();
6683                     if (wpir == null) {
6684                         it.remove();
6685                         continue;
6686                     }
6687                     PendingIntentRecord pir = wpir.get();
6688                     if (pir == null) {
6689                         it.remove();
6690                         continue;
6691                     }
6692                     if (packageName == null) {
6693                         // Stopping user, remove all objects for the user.
6694                         if (pir.key.userId != userId) {
6695                             // Not the same user, skip it.
6696                             continue;
6697                         }
6698                     } else {
6699                         if (UserHandle.getAppId(pir.uid) != appId) {
6700                             // Different app id, skip it.
6701                             continue;
6702                         }
6703                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6704                             // Different user, skip it.
6705                             continue;
6706                         }
6707                         if (!pir.key.packageName.equals(packageName)) {
6708                             // Different package, skip it.
6709                             continue;
6710                         }
6711                     }
6712                     if (!doit) {
6713                         return true;
6714                     }
6715                     didSomething = true;
6716                     it.remove();
6717                     makeIntentSenderCanceledLocked(pir);
6718                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6719                         pir.key.activity.pendingResults.remove(pir.ref);
6720                     }
6721                 }
6722             }
6723         }
6724
6725         if (doit) {
6726             if (purgeCache && packageName != null) {
6727                 AttributeCache ac = AttributeCache.instance();
6728                 if (ac != null) {
6729                     ac.removePackage(packageName);
6730                 }
6731             }
6732             if (mBooted) {
6733                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6734                 mStackSupervisor.scheduleIdleLocked();
6735             }
6736         }
6737
6738         return didSomething;
6739     }
6740
6741     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6742         return removeProcessNameLocked(name, uid, null);
6743     }
6744
6745     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6746             final ProcessRecord expecting) {
6747         ProcessRecord old = mProcessNames.get(name, uid);
6748         // Only actually remove when the currently recorded value matches the
6749         // record that we expected; if it doesn't match then we raced with a
6750         // newly created process and we don't want to destroy the new one.
6751         if ((expecting == null) || (old == expecting)) {
6752             mProcessNames.remove(name, uid);
6753         }
6754         if (old != null && old.uidRecord != null) {
6755             old.uidRecord.numProcs--;
6756             if (old.uidRecord.numProcs == 0) {
6757                 // No more processes using this uid, tell clients it is gone.
6758                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6759                         "No more processes in " + old.uidRecord);
6760                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6761                 EventLogTags.writeAmUidStopped(uid);
6762                 mActiveUids.remove(uid);
6763                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6764             }
6765             old.uidRecord = null;
6766         }
6767         mIsolatedProcesses.remove(uid);
6768         return old;
6769     }
6770
6771     private final void addProcessNameLocked(ProcessRecord proc) {
6772         // We shouldn't already have a process under this name, but just in case we
6773         // need to clean up whatever may be there now.
6774         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6775         if (old == proc && proc.persistent) {
6776             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6777             Slog.w(TAG, "Re-adding persistent process " + proc);
6778         } else if (old != null) {
6779             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6780         }
6781         UidRecord uidRec = mActiveUids.get(proc.uid);
6782         if (uidRec == null) {
6783             uidRec = new UidRecord(proc.uid);
6784             // This is the first appearance of the uid, report it now!
6785             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6786                     "Creating new process uid: " + uidRec);
6787             if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0
6788                     || mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) {
6789                 uidRec.setWhitelist = uidRec.curWhitelist = true;
6790             }
6791             uidRec.updateHasInternetPermission();
6792             mActiveUids.put(proc.uid, uidRec);
6793             EventLogTags.writeAmUidRunning(uidRec.uid);
6794             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6795         }
6796         proc.uidRecord = uidRec;
6797
6798         // Reset render thread tid if it was already set, so new process can set it again.
6799         proc.renderThreadTid = 0;
6800         uidRec.numProcs++;
6801         mProcessNames.put(proc.processName, proc.uid, proc);
6802         if (proc.isolated) {
6803             mIsolatedProcesses.put(proc.uid, proc);
6804         }
6805     }
6806
6807     boolean removeProcessLocked(ProcessRecord app,
6808             boolean callerWillRestart, boolean allowRestart, String reason) {
6809         final String name = app.processName;
6810         final int uid = app.uid;
6811         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6812             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6813
6814         ProcessRecord old = mProcessNames.get(name, uid);
6815         if (old != app) {
6816             // This process is no longer active, so nothing to do.
6817             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6818             return false;
6819         }
6820         removeProcessNameLocked(name, uid);
6821         if (mHeavyWeightProcess == app) {
6822             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6823                     mHeavyWeightProcess.userId, 0));
6824             mHeavyWeightProcess = null;
6825         }
6826         boolean needRestart = false;
6827         if (app.pid > 0 && app.pid != MY_PID) {
6828             int pid = app.pid;
6829             synchronized (mPidsSelfLocked) {
6830                 mPidsSelfLocked.remove(pid);
6831                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6832             }
6833             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6834             boolean willRestart = false;
6835             if (app.persistent && !app.isolated) {
6836                 if (!callerWillRestart) {
6837                     willRestart = true;
6838                 } else {
6839                     needRestart = true;
6840                 }
6841             }
6842             app.kill(reason, true);
6843             if (app.isolated) {
6844                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6845                 getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
6846             }
6847             handleAppDiedLocked(app, willRestart, allowRestart);
6848             if (willRestart) {
6849                 removeLruProcessLocked(app);
6850                 addAppLocked(app.info, null, false, null /* ABI override */);
6851             }
6852         } else {
6853             mRemovedProcesses.add(app);
6854         }
6855
6856         return needRestart;
6857     }
6858
6859     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6860         cleanupAppInLaunchingProvidersLocked(app, true);
6861         removeProcessLocked(app, false, true, "timeout publishing content providers");
6862     }
6863
6864     private final void processStartTimedOutLocked(ProcessRecord app) {
6865         final int pid = app.pid;
6866         boolean gone = false;
6867         synchronized (mPidsSelfLocked) {
6868             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6869             if (knownApp != null && knownApp.thread == null) {
6870                 mPidsSelfLocked.remove(pid);
6871                 gone = true;
6872             }
6873         }
6874
6875         if (gone) {
6876             Slog.w(TAG, "Process " + app + " failed to attach");
6877             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6878                     pid, app.uid, app.processName);
6879             removeProcessNameLocked(app.processName, app.uid);
6880             if (mHeavyWeightProcess == app) {
6881                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6882                         mHeavyWeightProcess.userId, 0));
6883                 mHeavyWeightProcess = null;
6884             }
6885             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6886             // Take care of any launching providers waiting for this process.
6887             cleanupAppInLaunchingProvidersLocked(app, true);
6888             // Take care of any services that are waiting for the process.
6889             mServices.processStartTimedOutLocked(app);
6890             app.kill("start timeout", true);
6891             if (app.isolated) {
6892                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6893             }
6894             removeLruProcessLocked(app);
6895             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6896                 Slog.w(TAG, "Unattached app died before backup, skipping");
6897                 mHandler.post(new Runnable() {
6898                 @Override
6899                     public void run(){
6900                         try {
6901                             IBackupManager bm = IBackupManager.Stub.asInterface(
6902                                     ServiceManager.getService(Context.BACKUP_SERVICE));
6903                             bm.agentDisconnected(app.info.packageName);
6904                         } catch (RemoteException e) {
6905                             // Can't happen; the backup manager is local
6906                         }
6907                     }
6908                 });
6909             }
6910             if (isPendingBroadcastProcessLocked(pid)) {
6911                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6912                 skipPendingBroadcastLocked(pid);
6913             }
6914         } else {
6915             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6916         }
6917     }
6918
6919     private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
6920             int pid) {
6921
6922         // Find the application record that is being attached...  either via
6923         // the pid if we are running in multiple processes, or just pull the
6924         // next app record if we are emulating process with anonymous threads.
6925         ProcessRecord app;
6926         long startTime = SystemClock.uptimeMillis();
6927         if (pid != MY_PID && pid >= 0) {
6928             synchronized (mPidsSelfLocked) {
6929                 app = mPidsSelfLocked.get(pid);
6930             }
6931         } else {
6932             app = null;
6933         }
6934
6935         if (app == null) {
6936             Slog.w(TAG, "No pending application record for pid " + pid
6937                     + " (IApplicationThread " + thread + "); dropping process");
6938             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6939             if (pid > 0 && pid != MY_PID) {
6940                 killProcessQuiet(pid);
6941                 //TODO: killProcessGroup(app.info.uid, pid);
6942             } else {
6943                 try {
6944                     thread.scheduleExit();
6945                 } catch (Exception e) {
6946                     // Ignore exceptions.
6947                 }
6948             }
6949             return false;
6950         }
6951
6952         // If this application record is still attached to a previous
6953         // process, clean it up now.
6954         if (app.thread != null) {
6955             handleAppDiedLocked(app, true, true);
6956         }
6957
6958         // Tell the process all about itself.
6959
6960         if (DEBUG_ALL) Slog.v(
6961                 TAG, "Binding process pid " + pid + " to record " + app);
6962
6963         final String processName = app.processName;
6964         try {
6965             AppDeathRecipient adr = new AppDeathRecipient(
6966                     app, pid, thread);
6967             thread.asBinder().linkToDeath(adr, 0);
6968             app.deathRecipient = adr;
6969         } catch (RemoteException e) {
6970             app.resetPackageList(mProcessStats);
6971             startProcessLocked(app, "link fail", processName);
6972             return false;
6973         }
6974
6975         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6976
6977         app.makeActive(thread, mProcessStats);
6978         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6979         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6980         app.forcingToImportant = null;
6981         updateProcessForegroundLocked(app, false, false);
6982         app.hasShownUi = false;
6983         app.debugging = false;
6984         app.cached = false;
6985         app.killedByAm = false;
6986         app.killed = false;
6987
6988
6989         // We carefully use the same state that PackageManager uses for
6990         // filtering, since we use this flag to decide if we need to install
6991         // providers when user is unlocked later
6992         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6993
6994         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6995
6996         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6997         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6998
6999         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
7000             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
7001             msg.obj = app;
7002             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
7003         }
7004
7005         checkTime(startTime, "attachApplicationLocked: before bindApplication");
7006
7007         if (!normalMode) {
7008             Slog.i(TAG, "Launching preboot mode app: " + app);
7009         }
7010
7011         if (DEBUG_ALL) Slog.v(
7012             TAG, "New app record " + app
7013             + " thread=" + thread.asBinder() + " pid=" + pid);
7014         try {
7015             int testMode = ApplicationThreadConstants.DEBUG_OFF;
7016             if (mDebugApp != null && mDebugApp.equals(processName)) {
7017                 testMode = mWaitForDebugger
7018                     ? ApplicationThreadConstants.DEBUG_WAIT
7019                     : ApplicationThreadConstants.DEBUG_ON;
7020                 app.debugging = true;
7021                 if (mDebugTransient) {
7022                     mDebugApp = mOrigDebugApp;
7023                     mWaitForDebugger = mOrigWaitForDebugger;
7024                 }
7025             }
7026
7027             ProfilerInfo profilerInfo = null;
7028             String agent = null;
7029             if (mProfileApp != null && mProfileApp.equals(processName)) {
7030                 mProfileProc = app;
7031                 profilerInfo = (mProfilerInfo != null && mProfilerInfo.profileFile != null) ?
7032                         new ProfilerInfo(mProfilerInfo) : null;
7033                 agent = mProfilerInfo != null ? mProfilerInfo.agent : null;
7034             } else if (app.instr != null && app.instr.mProfileFile != null) {
7035                 profilerInfo = new ProfilerInfo(app.instr.mProfileFile, null, 0, false, false,
7036                         null);
7037             }
7038
7039             boolean enableTrackAllocation = false;
7040             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
7041                 enableTrackAllocation = true;
7042                 mTrackAllocationApp = null;
7043             }
7044
7045             // If the app is being launched for restore or full backup, set it up specially
7046             boolean isRestrictedBackupMode = false;
7047             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
7048                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= FIRST_APPLICATION_UID
7049                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
7050                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
7051                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
7052             }
7053
7054             if (app.instr != null) {
7055                 notifyPackageUse(app.instr.mClass.getPackageName(),
7056                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
7057             }
7058             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
7059                     + processName + " with config " + getGlobalConfiguration());
7060             ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
7061             app.compat = compatibilityInfoForPackageLocked(appInfo);
7062
7063             if (profilerInfo != null && profilerInfo.profileFd != null) {
7064                 profilerInfo.profileFd = profilerInfo.profileFd.dup();
7065             }
7066
7067             // We deprecated Build.SERIAL and it is not accessible to
7068             // apps that target the v2 security sandbox. Since access to
7069             // the serial is now behind a permission we push down the value.
7070             String buildSerial = appInfo.targetSandboxVersion < 2
7071                     ? sTheRealBuildSerial : Build.UNKNOWN;
7072
7073             // Check if this is a secondary process that should be incorporated into some
7074             // currently active instrumentation.  (Note we do this AFTER all of the profiling
7075             // stuff above because profiling can currently happen only in the primary
7076             // instrumentation process.)
7077             if (mActiveInstrumentation.size() > 0 && app.instr == null) {
7078                 for (int i = mActiveInstrumentation.size() - 1; i >= 0 && app.instr == null; i--) {
7079                     ActiveInstrumentation aInstr = mActiveInstrumentation.get(i);
7080                     if (!aInstr.mFinished && aInstr.mTargetInfo.uid == app.uid) {
7081                         if (aInstr.mTargetProcesses.length == 0) {
7082                             // This is the wildcard mode, where every process brought up for
7083                             // the target instrumentation should be included.
7084                             if (aInstr.mTargetInfo.packageName.equals(app.info.packageName)) {
7085                                 app.instr = aInstr;
7086                                 aInstr.mRunningProcesses.add(app);
7087                             }
7088                         } else {
7089                             for (String proc : aInstr.mTargetProcesses) {
7090                                 if (proc.equals(app.processName)) {
7091                                     app.instr = aInstr;
7092                                     aInstr.mRunningProcesses.add(app);
7093                                     break;
7094                                 }
7095                             }
7096                         }
7097                     }
7098                 }
7099             }
7100
7101             // If we were asked to attach an agent on startup, do so now, before we're binding
7102             // application code.
7103             if (agent != null) {
7104                 thread.attachAgent(agent);
7105             }
7106
7107             checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
7108             mStackSupervisor.mActivityMetricsLogger.notifyBindApplication(app);
7109             if (app.instr != null) {
7110                 thread.bindApplication(processName, appInfo, providers,
7111                         app.instr.mClass,
7112                         profilerInfo, app.instr.mArguments,
7113                         app.instr.mWatcher,
7114                         app.instr.mUiAutomationConnection, testMode,
7115                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7116                         isRestrictedBackupMode || !normalMode, app.persistent,
7117                         new Configuration(getGlobalConfiguration()), app.compat,
7118                         getCommonServicesLocked(app.isolated),
7119                         mCoreSettingsObserver.getCoreSettingsLocked(),
7120                         buildSerial);
7121             } else {
7122                 thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
7123                         null, null, null, testMode,
7124                         mBinderTransactionTrackingEnabled, enableTrackAllocation,
7125                         isRestrictedBackupMode || !normalMode, app.persistent,
7126                         new Configuration(getGlobalConfiguration()), app.compat,
7127                         getCommonServicesLocked(app.isolated),
7128                         mCoreSettingsObserver.getCoreSettingsLocked(),
7129                         buildSerial);
7130             }
7131
7132             checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
7133             updateLruProcessLocked(app, false, null);
7134             checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
7135             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
7136         } catch (Exception e) {
7137             // todo: Yikes!  What should we do?  For now we will try to
7138             // start another process, but that could easily get us in
7139             // an infinite loop of restarting processes...
7140             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
7141
7142             app.resetPackageList(mProcessStats);
7143             app.unlinkDeathRecipient();
7144             startProcessLocked(app, "bind fail", processName);
7145             return false;
7146         }
7147
7148         // Remove this record from the list of starting applications.
7149         mPersistentStartingProcesses.remove(app);
7150         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
7151                 "Attach application locked removing on hold: " + app);
7152         mProcessesOnHold.remove(app);
7153
7154         boolean badApp = false;
7155         boolean didSomething = false;
7156
7157         // See if the top visible activity is waiting to run in this process...
7158         if (normalMode) {
7159             try {
7160                 if (mStackSupervisor.attachApplicationLocked(app)) {
7161                     didSomething = true;
7162                 }
7163             } catch (Exception e) {
7164                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
7165                 badApp = true;
7166             }
7167         }
7168
7169         // Find any services that should be running in this process...
7170         if (!badApp) {
7171             try {
7172                 didSomething |= mServices.attachApplicationLocked(app, processName);
7173                 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
7174             } catch (Exception e) {
7175                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
7176                 badApp = true;
7177             }
7178         }
7179
7180         // Check if a next-broadcast receiver is in this process...
7181         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
7182             try {
7183                 didSomething |= sendPendingBroadcastsLocked(app);
7184                 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
7185             } catch (Exception e) {
7186                 // If the app died trying to launch the receiver we declare it 'bad'
7187                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
7188                 badApp = true;
7189             }
7190         }
7191
7192         // Check whether the next backup agent is in this process...
7193         if (!badApp && mBackupTarget != null && mBackupTarget.app == app) {
7194             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
7195                     "New app is backup target, launching agent for " + app);
7196             notifyPackageUse(mBackupTarget.appInfo.packageName,
7197                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
7198             try {
7199                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
7200                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
7201                         mBackupTarget.backupMode);
7202             } catch (Exception e) {
7203                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
7204                 badApp = true;
7205             }
7206         }
7207
7208         if (badApp) {
7209             app.kill("error during init", true);
7210             handleAppDiedLocked(app, false, true);
7211             return false;
7212         }
7213
7214         if (!didSomething) {
7215             updateOomAdjLocked();
7216             checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
7217         }
7218
7219         return true;
7220     }
7221
7222     @Override
7223     public final void attachApplication(IApplicationThread thread) {
7224         if (thread == null) {
7225             throw new SecurityException("Invalid application interface");
7226         }
7227         synchronized (this) {
7228             int callingPid = Binder.getCallingPid();
7229             final long origId = Binder.clearCallingIdentity();
7230             attachApplicationLocked(thread, callingPid);
7231             Binder.restoreCallingIdentity(origId);
7232         }
7233     }
7234
7235     @Override
7236     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
7237         final long origId = Binder.clearCallingIdentity();
7238         synchronized (this) {
7239             ActivityStack stack = ActivityRecord.getStackLocked(token);
7240             if (stack != null) {
7241                 ActivityRecord r =
7242                         mStackSupervisor.activityIdleInternalLocked(token, false /* fromTimeout */,
7243                                 false /* processPausingActivities */, config);
7244                 if (stopProfiling) {
7245                     if ((mProfileProc == r.app) && mProfilerInfo != null) {
7246                         clearProfilerLocked();
7247                     }
7248                 }
7249             }
7250         }
7251         Binder.restoreCallingIdentity(origId);
7252     }
7253
7254     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
7255         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
7256                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
7257     }
7258
7259     void enableScreenAfterBoot() {
7260         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
7261                 SystemClock.uptimeMillis());
7262         mWindowManager.enableScreenAfterBoot();
7263
7264         synchronized (this) {
7265             updateEventDispatchingLocked();
7266         }
7267     }
7268
7269     @Override
7270     public void showBootMessage(final CharSequence msg, final boolean always) {
7271         if (Binder.getCallingUid() != myUid()) {
7272             throw new SecurityException();
7273         }
7274         mWindowManager.showBootMessage(msg, always);
7275     }
7276
7277     @Override
7278     public void keyguardGoingAway(int flags) {
7279         enforceNotIsolatedCaller("keyguardGoingAway");
7280         final long token = Binder.clearCallingIdentity();
7281         try {
7282             synchronized (this) {
7283                 mKeyguardController.keyguardGoingAway(flags);
7284             }
7285         } finally {
7286             Binder.restoreCallingIdentity(token);
7287         }
7288     }
7289
7290     /**
7291      * @return whther the keyguard is currently locked.
7292      */
7293     boolean isKeyguardLocked() {
7294         return mKeyguardController.isKeyguardLocked();
7295     }
7296
7297     final void finishBooting() {
7298         synchronized (this) {
7299             if (!mBootAnimationComplete) {
7300                 mCallFinishBooting = true;
7301                 return;
7302             }
7303             mCallFinishBooting = false;
7304         }
7305
7306         ArraySet<String> completedIsas = new ArraySet<String>();
7307         for (String abi : Build.SUPPORTED_ABIS) {
7308             zygoteProcess.establishZygoteConnectionForAbi(abi);
7309             final String instructionSet = VMRuntime.getInstructionSet(abi);
7310             if (!completedIsas.contains(instructionSet)) {
7311                 try {
7312                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
7313                 } catch (InstallerException e) {
7314                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
7315                             e.getMessage() +")");
7316                 }
7317                 completedIsas.add(instructionSet);
7318             }
7319         }
7320
7321         IntentFilter pkgFilter = new IntentFilter();
7322         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
7323         pkgFilter.addDataScheme("package");
7324         mContext.registerReceiver(new BroadcastReceiver() {
7325             @Override
7326             public void onReceive(Context context, Intent intent) {
7327                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
7328                 if (pkgs != null) {
7329                     for (String pkg : pkgs) {
7330                         synchronized (ActivityManagerService.this) {
7331                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
7332                                     0, "query restart")) {
7333                                 setResultCode(Activity.RESULT_OK);
7334                                 return;
7335                             }
7336                         }
7337                     }
7338                 }
7339             }
7340         }, pkgFilter);
7341
7342         IntentFilter dumpheapFilter = new IntentFilter();
7343         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
7344         mContext.registerReceiver(new BroadcastReceiver() {
7345             @Override
7346             public void onReceive(Context context, Intent intent) {
7347                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
7348                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
7349                 } else {
7350                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
7351                 }
7352             }
7353         }, dumpheapFilter);
7354
7355         // Let system services know.
7356         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
7357
7358         synchronized (this) {
7359             // Ensure that any processes we had put on hold are now started
7360             // up.
7361             final int NP = mProcessesOnHold.size();
7362             if (NP > 0) {
7363                 ArrayList<ProcessRecord> procs =
7364                     new ArrayList<ProcessRecord>(mProcessesOnHold);
7365                 for (int ip=0; ip<NP; ip++) {
7366                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
7367                             + procs.get(ip));
7368                     startProcessLocked(procs.get(ip), "on-hold", null);
7369                 }
7370             }
7371
7372             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
7373                 // Start looking for apps that are abusing wake locks.
7374                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_POWER_USE_MSG);
7375                 mHandler.sendMessageDelayed(nmsg, mConstants.POWER_CHECK_INTERVAL);
7376                 // Tell anyone interested that we are done booting!
7377                 SystemProperties.set("sys.boot_completed", "1");
7378
7379                 // And trigger dev.bootcomplete if we are not showing encryption progress
7380                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
7381                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
7382                     SystemProperties.set("dev.bootcomplete", "1");
7383                 }
7384                 mUserController.sendBootCompletedLocked(
7385                         new IIntentReceiver.Stub() {
7386                             @Override
7387                             public void performReceive(Intent intent, int resultCode,
7388                                     String data, Bundle extras, boolean ordered,
7389                                     boolean sticky, int sendingUser) {
7390                                 synchronized (ActivityManagerService.this) {
7391                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
7392                                             true, false);
7393                                 }
7394                             }
7395                         });
7396                 scheduleStartProfilesLocked();
7397             }
7398         }
7399     }
7400
7401     @Override
7402     public void bootAnimationComplete() {
7403         final boolean callFinishBooting;
7404         synchronized (this) {
7405             callFinishBooting = mCallFinishBooting;
7406             mBootAnimationComplete = true;
7407         }
7408         if (callFinishBooting) {
7409             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7410             finishBooting();
7411             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7412         }
7413     }
7414
7415     final void ensureBootCompleted() {
7416         boolean booting;
7417         boolean enableScreen;
7418         synchronized (this) {
7419             booting = mBooting;
7420             mBooting = false;
7421             enableScreen = !mBooted;
7422             mBooted = true;
7423         }
7424
7425         if (booting) {
7426             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
7427             finishBooting();
7428             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
7429         }
7430
7431         if (enableScreen) {
7432             enableScreenAfterBoot();
7433         }
7434     }
7435
7436     @Override
7437     public final void activityResumed(IBinder token) {
7438         final long origId = Binder.clearCallingIdentity();
7439         synchronized(this) {
7440             ActivityRecord.activityResumedLocked(token);
7441             mWindowManager.notifyAppResumedFinished(token);
7442         }
7443         Binder.restoreCallingIdentity(origId);
7444     }
7445
7446     @Override
7447     public final void activityPaused(IBinder token) {
7448         final long origId = Binder.clearCallingIdentity();
7449         synchronized(this) {
7450             ActivityStack stack = ActivityRecord.getStackLocked(token);
7451             if (stack != null) {
7452                 stack.activityPausedLocked(token, false);
7453             }
7454         }
7455         Binder.restoreCallingIdentity(origId);
7456     }
7457
7458     @Override
7459     public final void activityStopped(IBinder token, Bundle icicle,
7460             PersistableBundle persistentState, CharSequence description) {
7461         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
7462
7463         // Refuse possible leaked file descriptors
7464         if (icicle != null && icicle.hasFileDescriptors()) {
7465             throw new IllegalArgumentException("File descriptors passed in Bundle");
7466         }
7467
7468         final long origId = Binder.clearCallingIdentity();
7469
7470         synchronized (this) {
7471             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7472             if (r != null) {
7473                 r.activityStoppedLocked(icicle, persistentState, description);
7474             }
7475         }
7476
7477         trimApplications();
7478
7479         Binder.restoreCallingIdentity(origId);
7480     }
7481
7482     @Override
7483     public final void activityDestroyed(IBinder token) {
7484         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
7485         synchronized (this) {
7486             ActivityStack stack = ActivityRecord.getStackLocked(token);
7487             if (stack != null) {
7488                 stack.activityDestroyedLocked(token, "activityDestroyed");
7489             }
7490         }
7491     }
7492
7493     @Override
7494     public final void activityRelaunched(IBinder token) {
7495         final long origId = Binder.clearCallingIdentity();
7496         synchronized (this) {
7497             mStackSupervisor.activityRelaunchedLocked(token);
7498         }
7499         Binder.restoreCallingIdentity(origId);
7500     }
7501
7502     @Override
7503     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
7504             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
7505         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7506                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7507         synchronized (this) {
7508             ActivityRecord record = ActivityRecord.isInStackLocked(token);
7509             if (record == null) {
7510                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7511                         + "found for: " + token);
7512             }
7513             record.setSizeConfigurations(horizontalSizeConfiguration,
7514                     verticalSizeConfigurations, smallestSizeConfigurations);
7515         }
7516     }
7517
7518     @Override
7519     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7520         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7521     }
7522
7523     @Override
7524     public final void notifyEnterAnimationComplete(IBinder token) {
7525         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7526     }
7527
7528     @Override
7529     public String getCallingPackage(IBinder token) {
7530         synchronized (this) {
7531             ActivityRecord r = getCallingRecordLocked(token);
7532             return r != null ? r.info.packageName : null;
7533         }
7534     }
7535
7536     @Override
7537     public ComponentName getCallingActivity(IBinder token) {
7538         synchronized (this) {
7539             ActivityRecord r = getCallingRecordLocked(token);
7540             return r != null ? r.intent.getComponent() : null;
7541         }
7542     }
7543
7544     private ActivityRecord getCallingRecordLocked(IBinder token) {
7545         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7546         if (r == null) {
7547             return null;
7548         }
7549         return r.resultTo;
7550     }
7551
7552     @Override
7553     public ComponentName getActivityClassForToken(IBinder token) {
7554         synchronized(this) {
7555             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7556             if (r == null) {
7557                 return null;
7558             }
7559             return r.intent.getComponent();
7560         }
7561     }
7562
7563     @Override
7564     public String getPackageForToken(IBinder token) {
7565         synchronized(this) {
7566             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7567             if (r == null) {
7568                 return null;
7569             }
7570             return r.packageName;
7571         }
7572     }
7573
7574     @Override
7575     public boolean isRootVoiceInteraction(IBinder token) {
7576         synchronized(this) {
7577             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7578             if (r == null) {
7579                 return false;
7580             }
7581             return r.rootVoiceInteraction;
7582         }
7583     }
7584
7585     @Override
7586     public IIntentSender getIntentSender(int type,
7587             String packageName, IBinder token, String resultWho,
7588             int requestCode, Intent[] intents, String[] resolvedTypes,
7589             int flags, Bundle bOptions, int userId) {
7590         enforceNotIsolatedCaller("getIntentSender");
7591         // Refuse possible leaked file descriptors
7592         if (intents != null) {
7593             if (intents.length < 1) {
7594                 throw new IllegalArgumentException("Intents array length must be >= 1");
7595             }
7596             for (int i=0; i<intents.length; i++) {
7597                 Intent intent = intents[i];
7598                 if (intent != null) {
7599                     if (intent.hasFileDescriptors()) {
7600                         throw new IllegalArgumentException("File descriptors passed in Intent");
7601                     }
7602                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7603                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7604                         throw new IllegalArgumentException(
7605                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7606                     }
7607                     intents[i] = new Intent(intent);
7608                 }
7609             }
7610             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7611                 throw new IllegalArgumentException(
7612                         "Intent array length does not match resolvedTypes length");
7613             }
7614         }
7615         if (bOptions != null) {
7616             if (bOptions.hasFileDescriptors()) {
7617                 throw new IllegalArgumentException("File descriptors passed in options");
7618             }
7619         }
7620
7621         synchronized(this) {
7622             int callingUid = Binder.getCallingUid();
7623             int origUserId = userId;
7624             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7625                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7626                     ALLOW_NON_FULL, "getIntentSender", null);
7627             if (origUserId == UserHandle.USER_CURRENT) {
7628                 // We don't want to evaluate this until the pending intent is
7629                 // actually executed.  However, we do want to always do the
7630                 // security checking for it above.
7631                 userId = UserHandle.USER_CURRENT;
7632             }
7633             try {
7634                 if (callingUid != 0 && callingUid != SYSTEM_UID) {
7635                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7636                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7637                     if (!UserHandle.isSameApp(callingUid, uid)) {
7638                         String msg = "Permission Denial: getIntentSender() from pid="
7639                             + Binder.getCallingPid()
7640                             + ", uid=" + Binder.getCallingUid()
7641                             + ", (need uid=" + uid + ")"
7642                             + " is not allowed to send as package " + packageName;
7643                         Slog.w(TAG, msg);
7644                         throw new SecurityException(msg);
7645                     }
7646                 }
7647
7648                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7649                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7650
7651             } catch (RemoteException e) {
7652                 throw new SecurityException(e);
7653             }
7654         }
7655     }
7656
7657     IIntentSender getIntentSenderLocked(int type, String packageName,
7658             int callingUid, int userId, IBinder token, String resultWho,
7659             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7660             Bundle bOptions) {
7661         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7662         ActivityRecord activity = null;
7663         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7664             activity = ActivityRecord.isInStackLocked(token);
7665             if (activity == null) {
7666                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7667                 return null;
7668             }
7669             if (activity.finishing) {
7670                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7671                 return null;
7672             }
7673         }
7674
7675         // We're going to be splicing together extras before sending, so we're
7676         // okay poking into any contained extras.
7677         if (intents != null) {
7678             for (int i = 0; i < intents.length; i++) {
7679                 intents[i].setDefusable(true);
7680             }
7681         }
7682         Bundle.setDefusable(bOptions, true);
7683
7684         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7685         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7686         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7687         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7688                 |PendingIntent.FLAG_UPDATE_CURRENT);
7689
7690         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7691                 type, packageName, activity, resultWho,
7692                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7693         WeakReference<PendingIntentRecord> ref;
7694         ref = mIntentSenderRecords.get(key);
7695         PendingIntentRecord rec = ref != null ? ref.get() : null;
7696         if (rec != null) {
7697             if (!cancelCurrent) {
7698                 if (updateCurrent) {
7699                     if (rec.key.requestIntent != null) {
7700                         rec.key.requestIntent.replaceExtras(intents != null ?
7701                                 intents[intents.length - 1] : null);
7702                     }
7703                     if (intents != null) {
7704                         intents[intents.length-1] = rec.key.requestIntent;
7705                         rec.key.allIntents = intents;
7706                         rec.key.allResolvedTypes = resolvedTypes;
7707                     } else {
7708                         rec.key.allIntents = null;
7709                         rec.key.allResolvedTypes = null;
7710                     }
7711                 }
7712                 return rec;
7713             }
7714             makeIntentSenderCanceledLocked(rec);
7715             mIntentSenderRecords.remove(key);
7716         }
7717         if (noCreate) {
7718             return rec;
7719         }
7720         rec = new PendingIntentRecord(this, key, callingUid);
7721         mIntentSenderRecords.put(key, rec.ref);
7722         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7723             if (activity.pendingResults == null) {
7724                 activity.pendingResults
7725                         = new HashSet<WeakReference<PendingIntentRecord>>();
7726             }
7727             activity.pendingResults.add(rec.ref);
7728         }
7729         return rec;
7730     }
7731
7732     @Override
7733     public int sendIntentSender(IIntentSender target, IBinder whitelistToken, int code,
7734             Intent intent, String resolvedType,
7735             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7736         if (target instanceof PendingIntentRecord) {
7737             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7738                     whitelistToken, finishedReceiver, requiredPermission, options);
7739         } else {
7740             if (intent == null) {
7741                 // Weird case: someone has given us their own custom IIntentSender, and now
7742                 // they have someone else trying to send to it but of course this isn't
7743                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7744                 // supplying an Intent... but we never want to dispatch a null Intent to
7745                 // a receiver, so um...  let's make something up.
7746                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7747                 intent = new Intent(Intent.ACTION_MAIN);
7748             }
7749             try {
7750                 target.send(code, intent, resolvedType, whitelistToken, null,
7751                         requiredPermission, options);
7752             } catch (RemoteException e) {
7753             }
7754             // Platform code can rely on getting a result back when the send is done, but if
7755             // this intent sender is from outside of the system we can't rely on it doing that.
7756             // So instead we don't give it the result receiver, and instead just directly
7757             // report the finish immediately.
7758             if (finishedReceiver != null) {
7759                 try {
7760                     finishedReceiver.performReceive(intent, 0,
7761                             null, null, false, false, UserHandle.getCallingUserId());
7762                 } catch (RemoteException e) {
7763                 }
7764             }
7765             return 0;
7766         }
7767     }
7768
7769     @Override
7770     public void cancelIntentSender(IIntentSender sender) {
7771         if (!(sender instanceof PendingIntentRecord)) {
7772             return;
7773         }
7774         synchronized(this) {
7775             PendingIntentRecord rec = (PendingIntentRecord)sender;
7776             try {
7777                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7778                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7779                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7780                     String msg = "Permission Denial: cancelIntentSender() from pid="
7781                         + Binder.getCallingPid()
7782                         + ", uid=" + Binder.getCallingUid()
7783                         + " is not allowed to cancel package "
7784                         + rec.key.packageName;
7785                     Slog.w(TAG, msg);
7786                     throw new SecurityException(msg);
7787                 }
7788             } catch (RemoteException e) {
7789                 throw new SecurityException(e);
7790             }
7791             cancelIntentSenderLocked(rec, true);
7792         }
7793     }
7794
7795     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7796         makeIntentSenderCanceledLocked(rec);
7797         mIntentSenderRecords.remove(rec.key);
7798         if (cleanActivity && rec.key.activity != null) {
7799             rec.key.activity.pendingResults.remove(rec.ref);
7800         }
7801     }
7802
7803     void makeIntentSenderCanceledLocked(PendingIntentRecord rec) {
7804         rec.canceled = true;
7805         RemoteCallbackList<IResultReceiver> callbacks = rec.detachCancelListenersLocked();
7806         if (callbacks != null) {
7807             mHandler.obtainMessage(DISPATCH_PENDING_INTENT_CANCEL_MSG, callbacks).sendToTarget();
7808         }
7809     }
7810
7811     @Override
7812     public String getPackageForIntentSender(IIntentSender pendingResult) {
7813         if (!(pendingResult instanceof PendingIntentRecord)) {
7814             return null;
7815         }
7816         try {
7817             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7818             return res.key.packageName;
7819         } catch (ClassCastException e) {
7820         }
7821         return null;
7822     }
7823
7824     @Override
7825     public void registerIntentSenderCancelListener(IIntentSender sender, IResultReceiver receiver) {
7826         if (!(sender instanceof PendingIntentRecord)) {
7827             return;
7828         }
7829         synchronized(this) {
7830             ((PendingIntentRecord)sender).registerCancelListenerLocked(receiver);
7831         }
7832     }
7833
7834     @Override
7835     public void unregisterIntentSenderCancelListener(IIntentSender sender,
7836             IResultReceiver receiver) {
7837         if (!(sender instanceof PendingIntentRecord)) {
7838             return;
7839         }
7840         synchronized(this) {
7841             ((PendingIntentRecord)sender).unregisterCancelListenerLocked(receiver);
7842         }
7843     }
7844
7845     @Override
7846     public int getUidForIntentSender(IIntentSender sender) {
7847         if (sender instanceof PendingIntentRecord) {
7848             try {
7849                 PendingIntentRecord res = (PendingIntentRecord)sender;
7850                 return res.uid;
7851             } catch (ClassCastException e) {
7852             }
7853         }
7854         return -1;
7855     }
7856
7857     @Override
7858     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7859         if (!(pendingResult instanceof PendingIntentRecord)) {
7860             return false;
7861         }
7862         try {
7863             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7864             if (res.key.allIntents == null) {
7865                 return false;
7866             }
7867             for (int i=0; i<res.key.allIntents.length; i++) {
7868                 Intent intent = res.key.allIntents[i];
7869                 if (intent.getPackage() != null && intent.getComponent() != null) {
7870                     return false;
7871                 }
7872             }
7873             return true;
7874         } catch (ClassCastException e) {
7875         }
7876         return false;
7877     }
7878
7879     @Override
7880     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7881         if (!(pendingResult instanceof PendingIntentRecord)) {
7882             return false;
7883         }
7884         try {
7885             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7886             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7887                 return true;
7888             }
7889             return false;
7890         } catch (ClassCastException e) {
7891         }
7892         return false;
7893     }
7894
7895     @Override
7896     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7897         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7898                 "getIntentForIntentSender()");
7899         if (!(pendingResult instanceof PendingIntentRecord)) {
7900             return null;
7901         }
7902         try {
7903             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7904             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7905         } catch (ClassCastException e) {
7906         }
7907         return null;
7908     }
7909
7910     @Override
7911     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7912         if (!(pendingResult instanceof PendingIntentRecord)) {
7913             return null;
7914         }
7915         try {
7916             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7917             synchronized (this) {
7918                 return getTagForIntentSenderLocked(res, prefix);
7919             }
7920         } catch (ClassCastException e) {
7921         }
7922         return null;
7923     }
7924
7925     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7926         final Intent intent = res.key.requestIntent;
7927         if (intent != null) {
7928             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7929                     || res.lastTagPrefix.equals(prefix))) {
7930                 return res.lastTag;
7931             }
7932             res.lastTagPrefix = prefix;
7933             final StringBuilder sb = new StringBuilder(128);
7934             if (prefix != null) {
7935                 sb.append(prefix);
7936             }
7937             if (intent.getAction() != null) {
7938                 sb.append(intent.getAction());
7939             } else if (intent.getComponent() != null) {
7940                 intent.getComponent().appendShortString(sb);
7941             } else {
7942                 sb.append("?");
7943             }
7944             return res.lastTag = sb.toString();
7945         }
7946         return null;
7947     }
7948
7949     @Override
7950     public void setProcessLimit(int max) {
7951         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7952                 "setProcessLimit()");
7953         synchronized (this) {
7954             mConstants.setOverrideMaxCachedProcesses(max);
7955         }
7956         trimApplications();
7957     }
7958
7959     @Override
7960     public int getProcessLimit() {
7961         synchronized (this) {
7962             return mConstants.getOverrideMaxCachedProcesses();
7963         }
7964     }
7965
7966     void importanceTokenDied(ImportanceToken token) {
7967         synchronized (ActivityManagerService.this) {
7968             synchronized (mPidsSelfLocked) {
7969                 ImportanceToken cur
7970                     = mImportantProcesses.get(token.pid);
7971                 if (cur != token) {
7972                     return;
7973                 }
7974                 mImportantProcesses.remove(token.pid);
7975                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7976                 if (pr == null) {
7977                     return;
7978                 }
7979                 pr.forcingToImportant = null;
7980                 updateProcessForegroundLocked(pr, false, false);
7981             }
7982             updateOomAdjLocked();
7983         }
7984     }
7985
7986     @Override
7987     public void setProcessImportant(IBinder token, int pid, boolean isForeground, String reason) {
7988         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7989                 "setProcessImportant()");
7990         synchronized(this) {
7991             boolean changed = false;
7992
7993             synchronized (mPidsSelfLocked) {
7994                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7995                 if (pr == null && isForeground) {
7996                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7997                     return;
7998                 }
7999                 ImportanceToken oldToken = mImportantProcesses.get(pid);
8000                 if (oldToken != null) {
8001                     oldToken.token.unlinkToDeath(oldToken, 0);
8002                     mImportantProcesses.remove(pid);
8003                     if (pr != null) {
8004                         pr.forcingToImportant = null;
8005                     }
8006                     changed = true;
8007                 }
8008                 if (isForeground && token != null) {
8009                     ImportanceToken newToken = new ImportanceToken(pid, token, reason) {
8010                         @Override
8011                         public void binderDied() {
8012                             importanceTokenDied(this);
8013                         }
8014                     };
8015                     try {
8016                         token.linkToDeath(newToken, 0);
8017                         mImportantProcesses.put(pid, newToken);
8018                         pr.forcingToImportant = newToken;
8019                         changed = true;
8020                     } catch (RemoteException e) {
8021                         // If the process died while doing this, we will later
8022                         // do the cleanup with the process death link.
8023                     }
8024                 }
8025             }
8026
8027             if (changed) {
8028                 updateOomAdjLocked();
8029             }
8030         }
8031     }
8032
8033     @Override
8034     public boolean isAppForeground(int uid) throws RemoteException {
8035         synchronized (this) {
8036             UidRecord uidRec = mActiveUids.get(uid);
8037             if (uidRec == null || uidRec.idle) {
8038                 return false;
8039             }
8040             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
8041         }
8042     }
8043
8044     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
8045     // be guarded by permission checking.
8046     int getUidState(int uid) {
8047         synchronized (this) {
8048             return getUidStateLocked(uid);
8049         }
8050     }
8051
8052     int getUidStateLocked(int uid) {
8053         UidRecord uidRec = mActiveUids.get(uid);
8054         return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
8055     }
8056
8057     @Override
8058     public boolean isInMultiWindowMode(IBinder token) {
8059         final long origId = Binder.clearCallingIdentity();
8060         try {
8061             synchronized(this) {
8062                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8063                 if (r == null) {
8064                     return false;
8065                 }
8066                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
8067                 return !r.getTask().mFullscreen;
8068             }
8069         } finally {
8070             Binder.restoreCallingIdentity(origId);
8071         }
8072     }
8073
8074     @Override
8075     public boolean isInPictureInPictureMode(IBinder token) {
8076         final long origId = Binder.clearCallingIdentity();
8077         try {
8078             synchronized(this) {
8079                 return isInPictureInPictureMode(ActivityRecord.forTokenLocked(token));
8080             }
8081         } finally {
8082             Binder.restoreCallingIdentity(origId);
8083         }
8084     }
8085
8086     private boolean isInPictureInPictureMode(ActivityRecord r) {
8087         if (r == null || r.getStack() == null || !r.getStack().isPinnedStack() ||
8088                 r.getStack().isInStackLocked(r) == null) {
8089             return false;
8090         }
8091
8092         // If we are animating to fullscreen then we have already dispatched the PIP mode
8093         // changed, so we should reflect that check here as well.
8094         final PinnedActivityStack stack = r.getStack();
8095         final PinnedStackWindowController windowController = stack.getWindowContainerController();
8096         return !windowController.isAnimatingBoundsToFullscreen();
8097     }
8098
8099     @Override
8100     public boolean enterPictureInPictureMode(IBinder token, final PictureInPictureParams params) {
8101         final long origId = Binder.clearCallingIdentity();
8102         try {
8103             synchronized(this) {
8104                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8105                         "enterPictureInPictureMode", token, params);
8106
8107                 // If the activity is already in picture in picture mode, then just return early
8108                 if (isInPictureInPictureMode(r)) {
8109                     return true;
8110                 }
8111
8112                 // Activity supports picture-in-picture, now check that we can enter PiP at this
8113                 // point, if it is
8114                 if (!r.checkEnterPictureInPictureState("enterPictureInPictureMode",
8115                         false /* beforeStopping */)) {
8116                     return false;
8117                 }
8118
8119                 final Runnable enterPipRunnable = () -> {
8120                     // Only update the saved args from the args that are set
8121                     r.pictureInPictureArgs.copyOnlySet(params);
8122                     final float aspectRatio = r.pictureInPictureArgs.getAspectRatio();
8123                     final List<RemoteAction> actions = r.pictureInPictureArgs.getActions();
8124                     // Adjust the source bounds by the insets for the transition down
8125                     final Rect sourceBounds = new Rect(r.pictureInPictureArgs.getSourceRectHint());
8126                     mStackSupervisor.moveActivityToPinnedStackLocked(r, sourceBounds, aspectRatio,
8127                             true /* moveHomeStackToFront */, "enterPictureInPictureMode");
8128                     final PinnedActivityStack stack = mStackSupervisor.getStack(PINNED_STACK_ID);
8129                     stack.setPictureInPictureAspectRatio(aspectRatio);
8130                     stack.setPictureInPictureActions(actions);
8131
8132                     MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_ENTERED,
8133                             r.supportsEnterPipOnTaskSwitch);
8134                     logPictureInPictureArgs(params);
8135                 };
8136
8137                 if (isKeyguardLocked()) {
8138                     // If the keyguard is showing or occluded, then try and dismiss it before
8139                     // entering picture-in-picture (this will prompt the user to authenticate if the
8140                     // device is currently locked).
8141                     try {
8142                         dismissKeyguard(token, new IKeyguardDismissCallback.Stub() {
8143                             @Override
8144                             public void onDismissError() throws RemoteException {
8145                                 // Do nothing
8146                             }
8147
8148                             @Override
8149                             public void onDismissSucceeded() throws RemoteException {
8150                                 mHandler.post(enterPipRunnable);
8151                             }
8152
8153                             @Override
8154                             public void onDismissCancelled() throws RemoteException {
8155                                 // Do nothing
8156                             }
8157                         });
8158                     } catch (RemoteException e) {
8159                         // Local call
8160                     }
8161                 } else {
8162                     // Enter picture in picture immediately otherwise
8163                     enterPipRunnable.run();
8164                 }
8165                 return true;
8166             }
8167         } finally {
8168             Binder.restoreCallingIdentity(origId);
8169         }
8170     }
8171
8172     @Override
8173     public void setPictureInPictureParams(IBinder token, final PictureInPictureParams params) {
8174         final long origId = Binder.clearCallingIdentity();
8175         try {
8176             synchronized(this) {
8177                 final ActivityRecord r = ensureValidPictureInPictureActivityParamsLocked(
8178                         "setPictureInPictureParams", token, params);
8179
8180                 // Only update the saved args from the args that are set
8181                 r.pictureInPictureArgs.copyOnlySet(params);
8182                 if (r.getStack().getStackId() == PINNED_STACK_ID) {
8183                     // If the activity is already in picture-in-picture, update the pinned stack now
8184                     // if it is not already expanding to fullscreen. Otherwise, the arguments will
8185                     // be used the next time the activity enters PiP
8186                     final PinnedActivityStack stack = r.getStack();
8187                     if (!stack.isAnimatingBoundsToFullscreen()) {
8188                         stack.setPictureInPictureAspectRatio(
8189                                 r.pictureInPictureArgs.getAspectRatio());
8190                         stack.setPictureInPictureActions(r.pictureInPictureArgs.getActions());
8191                     }
8192                 }
8193                 logPictureInPictureArgs(params);
8194             }
8195         } finally {
8196             Binder.restoreCallingIdentity(origId);
8197         }
8198     }
8199
8200     @Override
8201     public int getMaxNumPictureInPictureActions(IBinder token) {
8202         // Currently, this is a static constant, but later, we may change this to be dependent on
8203         // the context of the activity
8204         return 3;
8205     }
8206
8207     private void logPictureInPictureArgs(PictureInPictureParams params) {
8208         if (params.hasSetActions()) {
8209             MetricsLogger.histogram(mContext, "tron_varz_picture_in_picture_actions_count",
8210                     params.getActions().size());
8211         }
8212         if (params.hasSetAspectRatio()) {
8213             LogMaker lm = new LogMaker(MetricsEvent.ACTION_PICTURE_IN_PICTURE_ASPECT_RATIO_CHANGED);
8214             lm.addTaggedData(MetricsEvent.PICTURE_IN_PICTURE_ASPECT_RATIO, params.getAspectRatio());
8215             MetricsLogger.action(lm);
8216         }
8217     }
8218
8219     /**
8220      * Checks the state of the system and the activity associated with the given {@param token} to
8221      * verify that picture-in-picture is supported for that activity.
8222      *
8223      * @return the activity record for the given {@param token} if all the checks pass.
8224      */
8225     private ActivityRecord ensureValidPictureInPictureActivityParamsLocked(String caller,
8226             IBinder token, PictureInPictureParams params) {
8227         if (!mSupportsPictureInPicture) {
8228             throw new IllegalStateException(caller
8229                     + ": Device doesn't support picture-in-picture mode.");
8230         }
8231
8232         final ActivityRecord r = ActivityRecord.forTokenLocked(token);
8233         if (r == null) {
8234             throw new IllegalStateException(caller
8235                     + ": Can't find activity for token=" + token);
8236         }
8237
8238         if (!r.supportsPictureInPicture()) {
8239             throw new IllegalStateException(caller
8240                     + ": Current activity does not support picture-in-picture.");
8241         }
8242
8243         if (!StackId.isAllowedToEnterPictureInPicture(r.getStack().getStackId())) {
8244             throw new IllegalStateException(caller
8245                     + ": Activities on the home, assistant, or recents stack not supported");
8246         }
8247
8248         if (params.hasSetAspectRatio()
8249                 && !mWindowManager.isValidPictureInPictureAspectRatio(r.getStack().mDisplayId,
8250                         params.getAspectRatio())) {
8251             final float minAspectRatio = mContext.getResources().getFloat(
8252                     com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
8253             final float maxAspectRatio = mContext.getResources().getFloat(
8254                     com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
8255             throw new IllegalArgumentException(String.format(caller
8256                     + ": Aspect ratio is too extreme (must be between %f and %f).",
8257                             minAspectRatio, maxAspectRatio));
8258         }
8259
8260         // Truncate the number of actions if necessary
8261         params.truncateActions(getMaxNumPictureInPictureActions(token));
8262
8263         return r;
8264     }
8265
8266     // =========================================================
8267     // PROCESS INFO
8268     // =========================================================
8269
8270     static class ProcessInfoService extends IProcessInfoService.Stub {
8271         final ActivityManagerService mActivityManagerService;
8272         ProcessInfoService(ActivityManagerService activityManagerService) {
8273             mActivityManagerService = activityManagerService;
8274         }
8275
8276         @Override
8277         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
8278             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8279                     /*in*/ pids, /*out*/ states, null);
8280         }
8281
8282         @Override
8283         public void getProcessStatesAndOomScoresFromPids(
8284                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8285             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
8286                     /*in*/ pids, /*out*/ states, /*out*/ scores);
8287         }
8288     }
8289
8290     /**
8291      * For each PID in the given input array, write the current process state
8292      * for that process into the states array, or -1 to indicate that no
8293      * process with the given PID exists. If scores array is provided, write
8294      * the oom score for the process into the scores array, with INVALID_ADJ
8295      * indicating the PID doesn't exist.
8296      */
8297     public void getProcessStatesAndOomScoresForPIDs(
8298             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
8299         if (scores != null) {
8300             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
8301                     "getProcessStatesAndOomScoresForPIDs()");
8302         }
8303
8304         if (pids == null) {
8305             throw new NullPointerException("pids");
8306         } else if (states == null) {
8307             throw new NullPointerException("states");
8308         } else if (pids.length != states.length) {
8309             throw new IllegalArgumentException("pids and states arrays have different lengths!");
8310         } else if (scores != null && pids.length != scores.length) {
8311             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
8312         }
8313
8314         synchronized (mPidsSelfLocked) {
8315             for (int i = 0; i < pids.length; i++) {
8316                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
8317                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
8318                         pr.curProcState;
8319                 if (scores != null) {
8320                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
8321                 }
8322             }
8323         }
8324     }
8325
8326     // =========================================================
8327     // PERMISSIONS
8328     // =========================================================
8329
8330     static class PermissionController extends IPermissionController.Stub {
8331         ActivityManagerService mActivityManagerService;
8332         PermissionController(ActivityManagerService activityManagerService) {
8333             mActivityManagerService = activityManagerService;
8334         }
8335
8336         @Override
8337         public boolean checkPermission(String permission, int pid, int uid) {
8338             return mActivityManagerService.checkPermission(permission, pid,
8339                     uid) == PackageManager.PERMISSION_GRANTED;
8340         }
8341
8342         @Override
8343         public String[] getPackagesForUid(int uid) {
8344             return mActivityManagerService.mContext.getPackageManager()
8345                     .getPackagesForUid(uid);
8346         }
8347
8348         @Override
8349         public boolean isRuntimePermission(String permission) {
8350             try {
8351                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
8352                         .getPermissionInfo(permission, 0);
8353                 return (info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
8354                         == PermissionInfo.PROTECTION_DANGEROUS;
8355             } catch (NameNotFoundException nnfe) {
8356                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
8357             }
8358             return false;
8359         }
8360     }
8361
8362     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
8363         @Override
8364         public int checkComponentPermission(String permission, int pid, int uid,
8365                 int owningUid, boolean exported) {
8366             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
8367                     owningUid, exported);
8368         }
8369
8370         @Override
8371         public Object getAMSLock() {
8372             return ActivityManagerService.this;
8373         }
8374     }
8375
8376     /**
8377      * This can be called with or without the global lock held.
8378      */
8379     int checkComponentPermission(String permission, int pid, int uid,
8380             int owningUid, boolean exported) {
8381         if (pid == MY_PID) {
8382             return PackageManager.PERMISSION_GRANTED;
8383         }
8384         return ActivityManager.checkComponentPermission(permission, uid,
8385                 owningUid, exported);
8386     }
8387
8388     /**
8389      * As the only public entry point for permissions checking, this method
8390      * can enforce the semantic that requesting a check on a null global
8391      * permission is automatically denied.  (Internally a null permission
8392      * string is used when calling {@link #checkComponentPermission} in cases
8393      * when only uid-based security is needed.)
8394      *
8395      * This can be called with or without the global lock held.
8396      */
8397     @Override
8398     public int checkPermission(String permission, int pid, int uid) {
8399         if (permission == null) {
8400             return PackageManager.PERMISSION_DENIED;
8401         }
8402         return checkComponentPermission(permission, pid, uid, -1, true);
8403     }
8404
8405     @Override
8406     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
8407         if (permission == null) {
8408             return PackageManager.PERMISSION_DENIED;
8409         }
8410
8411         // We might be performing an operation on behalf of an indirect binder
8412         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
8413         // client identity accordingly before proceeding.
8414         Identity tlsIdentity = sCallerIdentity.get();
8415         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8416             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
8417                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
8418             uid = tlsIdentity.uid;
8419             pid = tlsIdentity.pid;
8420         }
8421
8422         return checkComponentPermission(permission, pid, uid, -1, true);
8423     }
8424
8425     /**
8426      * Binder IPC calls go through the public entry point.
8427      * This can be called with or without the global lock held.
8428      */
8429     int checkCallingPermission(String permission) {
8430         return checkPermission(permission,
8431                 Binder.getCallingPid(),
8432                 UserHandle.getAppId(Binder.getCallingUid()));
8433     }
8434
8435     /**
8436      * This can be called with or without the global lock held.
8437      */
8438     void enforceCallingPermission(String permission, String func) {
8439         if (checkCallingPermission(permission)
8440                 == PackageManager.PERMISSION_GRANTED) {
8441             return;
8442         }
8443
8444         String msg = "Permission Denial: " + func + " from pid="
8445                 + Binder.getCallingPid()
8446                 + ", uid=" + Binder.getCallingUid()
8447                 + " requires " + permission;
8448         Slog.w(TAG, msg);
8449         throw new SecurityException(msg);
8450     }
8451
8452     /**
8453      * Determine if UID is holding permissions required to access {@link Uri} in
8454      * the given {@link ProviderInfo}. Final permission checking is always done
8455      * in {@link ContentProvider}.
8456      */
8457     private final boolean checkHoldingPermissionsLocked(
8458             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
8459         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8460                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
8461         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
8462             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
8463                     != PERMISSION_GRANTED) {
8464                 return false;
8465             }
8466         }
8467         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
8468     }
8469
8470     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
8471             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
8472         if (pi.applicationInfo.uid == uid) {
8473             return true;
8474         } else if (!pi.exported) {
8475             return false;
8476         }
8477
8478         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
8479         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
8480         try {
8481             // check if target holds top-level <provider> permissions
8482             if (!readMet && pi.readPermission != null && considerUidPermissions
8483                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
8484                 readMet = true;
8485             }
8486             if (!writeMet && pi.writePermission != null && considerUidPermissions
8487                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
8488                 writeMet = true;
8489             }
8490
8491             // track if unprotected read/write is allowed; any denied
8492             // <path-permission> below removes this ability
8493             boolean allowDefaultRead = pi.readPermission == null;
8494             boolean allowDefaultWrite = pi.writePermission == null;
8495
8496             // check if target holds any <path-permission> that match uri
8497             final PathPermission[] pps = pi.pathPermissions;
8498             if (pps != null) {
8499                 final String path = grantUri.uri.getPath();
8500                 int i = pps.length;
8501                 while (i > 0 && (!readMet || !writeMet)) {
8502                     i--;
8503                     PathPermission pp = pps[i];
8504                     if (pp.match(path)) {
8505                         if (!readMet) {
8506                             final String pprperm = pp.getReadPermission();
8507                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8508                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
8509                                     + ": match=" + pp.match(path)
8510                                     + " check=" + pm.checkUidPermission(pprperm, uid));
8511                             if (pprperm != null) {
8512                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
8513                                         == PERMISSION_GRANTED) {
8514                                     readMet = true;
8515                                 } else {
8516                                     allowDefaultRead = false;
8517                                 }
8518                             }
8519                         }
8520                         if (!writeMet) {
8521                             final String ppwperm = pp.getWritePermission();
8522                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8523                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
8524                                     + ": match=" + pp.match(path)
8525                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
8526                             if (ppwperm != null) {
8527                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
8528                                         == PERMISSION_GRANTED) {
8529                                     writeMet = true;
8530                                 } else {
8531                                     allowDefaultWrite = false;
8532                                 }
8533                             }
8534                         }
8535                     }
8536                 }
8537             }
8538
8539             // grant unprotected <provider> read/write, if not blocked by
8540             // <path-permission> above
8541             if (allowDefaultRead) readMet = true;
8542             if (allowDefaultWrite) writeMet = true;
8543
8544         } catch (RemoteException e) {
8545             return false;
8546         }
8547
8548         return readMet && writeMet;
8549     }
8550
8551     public boolean isAppStartModeDisabled(int uid, String packageName) {
8552         synchronized (this) {
8553             return getAppStartModeLocked(uid, packageName, 0, -1, false, true)
8554                     == ActivityManager.APP_START_MODE_DISABLED;
8555         }
8556     }
8557
8558     // Unified app-op and target sdk check
8559     int appRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8560         // Apps that target O+ are always subject to background check
8561         if (packageTargetSdk >= Build.VERSION_CODES.O) {
8562             if (DEBUG_BACKGROUND_CHECK) {
8563                 Slog.i(TAG, "App " + uid + "/" + packageName + " targets O+, restricted");
8564             }
8565             return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8566         }
8567         // ...and legacy apps get an AppOp check
8568         int appop = mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
8569                 uid, packageName);
8570         if (DEBUG_BACKGROUND_CHECK) {
8571             Slog.i(TAG, "Legacy app " + uid + "/" + packageName + " bg appop " + appop);
8572         }
8573         switch (appop) {
8574             case AppOpsManager.MODE_ALLOWED:
8575                 return ActivityManager.APP_START_MODE_NORMAL;
8576             case AppOpsManager.MODE_IGNORED:
8577                 return ActivityManager.APP_START_MODE_DELAYED;
8578             default:
8579                 return ActivityManager.APP_START_MODE_DELAYED_RIGID;
8580         }
8581     }
8582
8583     // Service launch is available to apps with run-in-background exemptions but
8584     // some other background operations are not.  If we're doing a check
8585     // of service-launch policy, allow those callers to proceed unrestricted.
8586     int appServicesRestrictedInBackgroundLocked(int uid, String packageName, int packageTargetSdk) {
8587         // Persistent app?
8588         if (mPackageManagerInt.isPackagePersistent(packageName)) {
8589             if (DEBUG_BACKGROUND_CHECK) {
8590                 Slog.i(TAG, "App " + uid + "/" + packageName
8591                         + " is persistent; not restricted in background");
8592             }
8593             return ActivityManager.APP_START_MODE_NORMAL;
8594         }
8595
8596         // Non-persistent but background whitelisted?
8597         if (uidOnBackgroundWhitelist(uid)) {
8598             if (DEBUG_BACKGROUND_CHECK) {
8599                 Slog.i(TAG, "App " + uid + "/" + packageName
8600                         + " on background whitelist; not restricted in background");
8601             }
8602             return ActivityManager.APP_START_MODE_NORMAL;
8603         }
8604
8605         // Is this app on the battery whitelist?
8606         if (isOnDeviceIdleWhitelistLocked(uid)) {
8607             if (DEBUG_BACKGROUND_CHECK) {
8608                 Slog.i(TAG, "App " + uid + "/" + packageName
8609                         + " on idle whitelist; not restricted in background");
8610             }
8611             return ActivityManager.APP_START_MODE_NORMAL;
8612         }
8613
8614         // None of the service-policy criteria apply, so we apply the common criteria
8615         return appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk);
8616     }
8617
8618     int getAppStartModeLocked(int uid, String packageName, int packageTargetSdk,
8619             int callingPid, boolean alwaysRestrict, boolean disabledOnly) {
8620         UidRecord uidRec = mActiveUids.get(uid);
8621         if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid + " pkg="
8622                 + packageName + " rec=" + uidRec + " always=" + alwaysRestrict + " idle="
8623                 + (uidRec != null ? uidRec.idle : false));
8624         if (uidRec == null || alwaysRestrict || uidRec.idle) {
8625             boolean ephemeral;
8626             if (uidRec == null) {
8627                 ephemeral = getPackageManagerInternalLocked().isPackageEphemeral(
8628                         UserHandle.getUserId(uid), packageName);
8629             } else {
8630                 ephemeral = uidRec.ephemeral;
8631             }
8632
8633             if (ephemeral) {
8634                 // We are hard-core about ephemeral apps not running in the background.
8635                 return ActivityManager.APP_START_MODE_DISABLED;
8636             } else {
8637                 if (disabledOnly) {
8638                     // The caller is only interested in whether app starts are completely
8639                     // disabled for the given package (that is, it is an instant app).  So
8640                     // we don't need to go further, which is all just seeing if we should
8641                     // apply a "delayed" mode for a regular app.
8642                     return ActivityManager.APP_START_MODE_NORMAL;
8643                 }
8644                 final int startMode = (alwaysRestrict)
8645                         ? appRestrictedInBackgroundLocked(uid, packageName, packageTargetSdk)
8646                         : appServicesRestrictedInBackgroundLocked(uid, packageName,
8647                                 packageTargetSdk);
8648                 if (DEBUG_BACKGROUND_CHECK) Slog.d(TAG, "checkAllowBackground: uid=" + uid
8649                         + " pkg=" + packageName + " startMode=" + startMode
8650                         + " onwhitelist=" + isOnDeviceIdleWhitelistLocked(uid));
8651                 if (startMode == ActivityManager.APP_START_MODE_DELAYED) {
8652                     // This is an old app that has been forced into a "compatible as possible"
8653                     // mode of background check.  To increase compatibility, we will allow other
8654                     // foreground apps to cause its services to start.
8655                     if (callingPid >= 0) {
8656                         ProcessRecord proc;
8657                         synchronized (mPidsSelfLocked) {
8658                             proc = mPidsSelfLocked.get(callingPid);
8659                         }
8660                         if (proc != null &&
8661                                 !ActivityManager.isProcStateBackground(proc.curProcState)) {
8662                             // Whoever is instigating this is in the foreground, so we will allow it
8663                             // to go through.
8664                             return ActivityManager.APP_START_MODE_NORMAL;
8665                         }
8666                     }
8667                 }
8668                 return startMode;
8669             }
8670         }
8671         return ActivityManager.APP_START_MODE_NORMAL;
8672     }
8673
8674     boolean isOnDeviceIdleWhitelistLocked(int uid) {
8675         final int appId = UserHandle.getAppId(uid);
8676         return Arrays.binarySearch(mDeviceIdleWhitelist, appId) >= 0
8677                 || Arrays.binarySearch(mDeviceIdleTempWhitelist, appId) >= 0
8678                 || mPendingTempWhitelist.indexOfKey(uid) >= 0;
8679     }
8680
8681     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
8682         ProviderInfo pi = null;
8683         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
8684         if (cpr != null) {
8685             pi = cpr.info;
8686         } else {
8687             try {
8688                 pi = AppGlobals.getPackageManager().resolveContentProvider(
8689                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
8690                         userHandle);
8691             } catch (RemoteException ex) {
8692             }
8693         }
8694         return pi;
8695     }
8696
8697     void grantEphemeralAccessLocked(int userId, Intent intent,
8698             int targetAppId, int ephemeralAppId) {
8699         getPackageManagerInternalLocked().
8700                 grantEphemeralAccess(userId, intent, targetAppId, ephemeralAppId);
8701     }
8702
8703     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
8704         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8705         if (targetUris != null) {
8706             return targetUris.get(grantUri);
8707         }
8708         return null;
8709     }
8710
8711     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
8712             String targetPkg, int targetUid, GrantUri grantUri) {
8713         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
8714         if (targetUris == null) {
8715             targetUris = Maps.newArrayMap();
8716             mGrantedUriPermissions.put(targetUid, targetUris);
8717         }
8718
8719         UriPermission perm = targetUris.get(grantUri);
8720         if (perm == null) {
8721             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
8722             targetUris.put(grantUri, perm);
8723         }
8724
8725         return perm;
8726     }
8727
8728     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8729             final int modeFlags) {
8730         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8731         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8732                 : UriPermission.STRENGTH_OWNED;
8733
8734         // Root gets to do everything.
8735         if (uid == 0) {
8736             return true;
8737         }
8738
8739         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8740         if (perms == null) return false;
8741
8742         // First look for exact match
8743         final UriPermission exactPerm = perms.get(grantUri);
8744         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8745             return true;
8746         }
8747
8748         // No exact match, look for prefixes
8749         final int N = perms.size();
8750         for (int i = 0; i < N; i++) {
8751             final UriPermission perm = perms.valueAt(i);
8752             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8753                     && perm.getStrength(modeFlags) >= minStrength) {
8754                 return true;
8755             }
8756         }
8757
8758         return false;
8759     }
8760
8761     /**
8762      * @param uri This uri must NOT contain an embedded userId.
8763      * @param userId The userId in which the uri is to be resolved.
8764      */
8765     @Override
8766     public int checkUriPermission(Uri uri, int pid, int uid,
8767             final int modeFlags, int userId, IBinder callerToken) {
8768         enforceNotIsolatedCaller("checkUriPermission");
8769
8770         // Another redirected-binder-call permissions check as in
8771         // {@link checkPermissionWithToken}.
8772         Identity tlsIdentity = sCallerIdentity.get();
8773         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8774             uid = tlsIdentity.uid;
8775             pid = tlsIdentity.pid;
8776         }
8777
8778         // Our own process gets to do everything.
8779         if (pid == MY_PID) {
8780             return PackageManager.PERMISSION_GRANTED;
8781         }
8782         synchronized (this) {
8783             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8784                     ? PackageManager.PERMISSION_GRANTED
8785                     : PackageManager.PERMISSION_DENIED;
8786         }
8787     }
8788
8789     /**
8790      * Check if the targetPkg can be granted permission to access uri by
8791      * the callingUid using the given modeFlags.  Throws a security exception
8792      * if callingUid is not allowed to do this.  Returns the uid of the target
8793      * if the URI permission grant should be performed; returns -1 if it is not
8794      * needed (for example targetPkg already has permission to access the URI).
8795      * If you already know the uid of the target, you can supply it in
8796      * lastTargetUid else set that to -1.
8797      */
8798     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8799             final int modeFlags, int lastTargetUid) {
8800         if (!Intent.isAccessUriMode(modeFlags)) {
8801             return -1;
8802         }
8803
8804         if (targetPkg != null) {
8805             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8806                     "Checking grant " + targetPkg + " permission to " + grantUri);
8807         }
8808
8809         final IPackageManager pm = AppGlobals.getPackageManager();
8810
8811         // If this is not a content: uri, we can't do anything with it.
8812         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8813             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8814                     "Can't grant URI permission for non-content URI: " + grantUri);
8815             return -1;
8816         }
8817
8818         // Bail early if system is trying to hand out permissions directly; it
8819         // must always grant permissions on behalf of someone explicit.
8820         final int callingAppId = UserHandle.getAppId(callingUid);
8821         if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
8822             if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
8823                 // Exempted authority for cropping user photos in Settings app
8824             } else {
8825                 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8826                         + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8827                 return -1;
8828             }
8829         }
8830
8831         final String authority = grantUri.uri.getAuthority();
8832         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8833                 MATCH_DEBUG_TRIAGED_MISSING);
8834         if (pi == null) {
8835             Slog.w(TAG, "No content provider found for permission check: " +
8836                     grantUri.uri.toSafeString());
8837             return -1;
8838         }
8839
8840         int targetUid = lastTargetUid;
8841         if (targetUid < 0 && targetPkg != null) {
8842             try {
8843                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8844                         UserHandle.getUserId(callingUid));
8845                 if (targetUid < 0) {
8846                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8847                             "Can't grant URI permission no uid for: " + targetPkg);
8848                     return -1;
8849                 }
8850             } catch (RemoteException ex) {
8851                 return -1;
8852             }
8853         }
8854
8855         // Figure out the value returned when access is allowed
8856         final int allowedResult;
8857         if ((modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) {
8858             // If we're extending a persistable grant, then we need to return
8859             // "targetUid" so that we always create a grant data structure to
8860             // support take/release APIs
8861             allowedResult = targetUid;
8862         } else {
8863             // Otherwise, we can return "-1" to indicate that no grant data
8864             // structures need to be created
8865             allowedResult = -1;
8866         }
8867
8868         if (targetUid >= 0) {
8869             // First...  does the target actually need this permission?
8870             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8871                 // No need to grant the target this permission.
8872                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8873                         "Target " + targetPkg + " already has full permission to " + grantUri);
8874                 return allowedResult;
8875             }
8876         } else {
8877             // First...  there is no target package, so can anyone access it?
8878             boolean allowed = pi.exported;
8879             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8880                 if (pi.readPermission != null) {
8881                     allowed = false;
8882                 }
8883             }
8884             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8885                 if (pi.writePermission != null) {
8886                     allowed = false;
8887                 }
8888             }
8889             if (allowed) {
8890                 return allowedResult;
8891             }
8892         }
8893
8894         /* There is a special cross user grant if:
8895          * - The target is on another user.
8896          * - Apps on the current user can access the uri without any uid permissions.
8897          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8898          * grant uri permissions.
8899          */
8900         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8901                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8902                 modeFlags, false /*without considering the uid permissions*/);
8903
8904         // Second...  is the provider allowing granting of URI permissions?
8905         if (!specialCrossUserGrant) {
8906             if (!pi.grantUriPermissions) {
8907                 throw new SecurityException("Provider " + pi.packageName
8908                         + "/" + pi.name
8909                         + " does not allow granting of Uri permissions (uri "
8910                         + grantUri + ")");
8911             }
8912             if (pi.uriPermissionPatterns != null) {
8913                 final int N = pi.uriPermissionPatterns.length;
8914                 boolean allowed = false;
8915                 for (int i=0; i<N; i++) {
8916                     if (pi.uriPermissionPatterns[i] != null
8917                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8918                         allowed = true;
8919                         break;
8920                     }
8921                 }
8922                 if (!allowed) {
8923                     throw new SecurityException("Provider " + pi.packageName
8924                             + "/" + pi.name
8925                             + " does not allow granting of permission to path of Uri "
8926                             + grantUri);
8927                 }
8928             }
8929         }
8930
8931         // Third...  does the caller itself have permission to access
8932         // this uri?
8933         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8934             // Require they hold a strong enough Uri permission
8935             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8936                 if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(pi.readPermission)) {
8937                     throw new SecurityException(
8938                             "UID " + callingUid + " does not have permission to " + grantUri
8939                                     + "; you could obtain access using ACTION_OPEN_DOCUMENT "
8940                                     + "or related APIs");
8941                 } else {
8942                     throw new SecurityException(
8943                             "UID " + callingUid + " does not have permission to " + grantUri);
8944                 }
8945             }
8946         }
8947         return targetUid;
8948     }
8949
8950     /**
8951      * @param uri This uri must NOT contain an embedded userId.
8952      * @param userId The userId in which the uri is to be resolved.
8953      */
8954     @Override
8955     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8956             final int modeFlags, int userId) {
8957         enforceNotIsolatedCaller("checkGrantUriPermission");
8958         synchronized(this) {
8959             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8960                     new GrantUri(userId, uri, false), modeFlags, -1);
8961         }
8962     }
8963
8964     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8965             final int modeFlags, UriPermissionOwner owner) {
8966         if (!Intent.isAccessUriMode(modeFlags)) {
8967             return;
8968         }
8969
8970         // So here we are: the caller has the assumed permission
8971         // to the uri, and the target doesn't.  Let's now give this to
8972         // the target.
8973
8974         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8975                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8976
8977         final String authority = grantUri.uri.getAuthority();
8978         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8979                 MATCH_DEBUG_TRIAGED_MISSING);
8980         if (pi == null) {
8981             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8982             return;
8983         }
8984
8985         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8986             grantUri.prefix = true;
8987         }
8988         final UriPermission perm = findOrCreateUriPermissionLocked(
8989                 pi.packageName, targetPkg, targetUid, grantUri);
8990         perm.grantModes(modeFlags, owner);
8991     }
8992
8993     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8994             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8995         if (targetPkg == null) {
8996             throw new NullPointerException("targetPkg");
8997         }
8998         int targetUid;
8999         final IPackageManager pm = AppGlobals.getPackageManager();
9000         try {
9001             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
9002         } catch (RemoteException ex) {
9003             return;
9004         }
9005
9006         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
9007                 targetUid);
9008         if (targetUid < 0) {
9009             return;
9010         }
9011
9012         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
9013                 owner);
9014     }
9015
9016     static class NeededUriGrants extends ArrayList<GrantUri> {
9017         final String targetPkg;
9018         final int targetUid;
9019         final int flags;
9020
9021         NeededUriGrants(String targetPkg, int targetUid, int flags) {
9022             this.targetPkg = targetPkg;
9023             this.targetUid = targetUid;
9024             this.flags = flags;
9025         }
9026     }
9027
9028     /**
9029      * Like checkGrantUriPermissionLocked, but takes an Intent.
9030      */
9031     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
9032             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
9033         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9034                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
9035                 + " clip=" + (intent != null ? intent.getClipData() : null)
9036                 + " from " + intent + "; flags=0x"
9037                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
9038
9039         if (targetPkg == null) {
9040             throw new NullPointerException("targetPkg");
9041         }
9042
9043         if (intent == null) {
9044             return null;
9045         }
9046         Uri data = intent.getData();
9047         ClipData clip = intent.getClipData();
9048         if (data == null && clip == null) {
9049             return null;
9050         }
9051         // Default userId for uris in the intent (if they don't specify it themselves)
9052         int contentUserHint = intent.getContentUserHint();
9053         if (contentUserHint == UserHandle.USER_CURRENT) {
9054             contentUserHint = UserHandle.getUserId(callingUid);
9055         }
9056         final IPackageManager pm = AppGlobals.getPackageManager();
9057         int targetUid;
9058         if (needed != null) {
9059             targetUid = needed.targetUid;
9060         } else {
9061             try {
9062                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
9063                         targetUserId);
9064             } catch (RemoteException ex) {
9065                 return null;
9066             }
9067             if (targetUid < 0) {
9068                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9069                         "Can't grant URI permission no uid for: " + targetPkg
9070                         + " on user " + targetUserId);
9071                 return null;
9072             }
9073         }
9074         if (data != null) {
9075             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
9076             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9077                     targetUid);
9078             if (targetUid > 0) {
9079                 if (needed == null) {
9080                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
9081                 }
9082                 needed.add(grantUri);
9083             }
9084         }
9085         if (clip != null) {
9086             for (int i=0; i<clip.getItemCount(); i++) {
9087                 Uri uri = clip.getItemAt(i).getUri();
9088                 if (uri != null) {
9089                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
9090                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
9091                             targetUid);
9092                     if (targetUid > 0) {
9093                         if (needed == null) {
9094                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
9095                         }
9096                         needed.add(grantUri);
9097                     }
9098                 } else {
9099                     Intent clipIntent = clip.getItemAt(i).getIntent();
9100                     if (clipIntent != null) {
9101                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
9102                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
9103                         if (newNeeded != null) {
9104                             needed = newNeeded;
9105                         }
9106                     }
9107                 }
9108             }
9109         }
9110
9111         return needed;
9112     }
9113
9114     /**
9115      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
9116      */
9117     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
9118             UriPermissionOwner owner) {
9119         if (needed != null) {
9120             for (int i=0; i<needed.size(); i++) {
9121                 GrantUri grantUri = needed.get(i);
9122                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
9123                         grantUri, needed.flags, owner);
9124             }
9125         }
9126     }
9127
9128     void grantUriPermissionFromIntentLocked(int callingUid,
9129             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
9130         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
9131                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
9132         if (needed == null) {
9133             return;
9134         }
9135
9136         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
9137     }
9138
9139     /**
9140      * @param uri This uri must NOT contain an embedded userId.
9141      * @param userId The userId in which the uri is to be resolved.
9142      */
9143     @Override
9144     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
9145             final int modeFlags, int userId) {
9146         enforceNotIsolatedCaller("grantUriPermission");
9147         GrantUri grantUri = new GrantUri(userId, uri, false);
9148         synchronized(this) {
9149             final ProcessRecord r = getRecordForAppLocked(caller);
9150             if (r == null) {
9151                 throw new SecurityException("Unable to find app for caller "
9152                         + caller
9153                         + " when granting permission to uri " + grantUri);
9154             }
9155             if (targetPkg == null) {
9156                 throw new IllegalArgumentException("null target");
9157             }
9158             if (grantUri == null) {
9159                 throw new IllegalArgumentException("null uri");
9160             }
9161
9162             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
9163                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
9164                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
9165                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
9166
9167             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
9168                     UserHandle.getUserId(r.uid));
9169         }
9170     }
9171
9172     void removeUriPermissionIfNeededLocked(UriPermission perm) {
9173         if (perm.modeFlags == 0) {
9174             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9175                     perm.targetUid);
9176             if (perms != null) {
9177                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9178                         "Removing " + perm.targetUid + " permission to " + perm.uri);
9179
9180                 perms.remove(perm.uri);
9181                 if (perms.isEmpty()) {
9182                     mGrantedUriPermissions.remove(perm.targetUid);
9183                 }
9184             }
9185         }
9186     }
9187
9188     private void revokeUriPermissionLocked(String targetPackage, int callingUid, GrantUri grantUri,
9189             final int modeFlags) {
9190         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9191                 "Revoking all granted permissions to " + grantUri);
9192
9193         final IPackageManager pm = AppGlobals.getPackageManager();
9194         final String authority = grantUri.uri.getAuthority();
9195         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
9196                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9197         if (pi == null) {
9198             Slog.w(TAG, "No content provider found for permission revoke: "
9199                     + grantUri.toSafeString());
9200             return;
9201         }
9202
9203         // Does the caller have this permission on the URI?
9204         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
9205             // If they don't have direct access to the URI, then revoke any
9206             // ownerless URI permissions that have been granted to them.
9207             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9208             if (perms != null) {
9209                 boolean persistChanged = false;
9210                 for (int i = perms.size()-1; i >= 0; i--) {
9211                     final UriPermission perm = perms.valueAt(i);
9212                     if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9213                         continue;
9214                     }
9215                     if (perm.uri.sourceUserId == grantUri.sourceUserId
9216                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9217                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9218                                 "Revoking non-owned " + perm.targetUid
9219                                 + " permission to " + perm.uri);
9220                         persistChanged |= perm.revokeModes(
9221                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
9222                         if (perm.modeFlags == 0) {
9223                             perms.removeAt(i);
9224                         }
9225                     }
9226                 }
9227                 if (perms.isEmpty()) {
9228                     mGrantedUriPermissions.remove(callingUid);
9229                 }
9230                 if (persistChanged) {
9231                     schedulePersistUriGrants();
9232                 }
9233             }
9234             return;
9235         }
9236
9237         boolean persistChanged = false;
9238
9239         // Go through all of the permissions and remove any that match.
9240         for (int i = mGrantedUriPermissions.size()-1; i >= 0; i--) {
9241             final int targetUid = mGrantedUriPermissions.keyAt(i);
9242             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9243
9244             for (int j = perms.size()-1; j >= 0; j--) {
9245                 final UriPermission perm = perms.valueAt(j);
9246                 if (targetPackage != null && !targetPackage.equals(perm.targetPkg)) {
9247                     continue;
9248                 }
9249                 if (perm.uri.sourceUserId == grantUri.sourceUserId
9250                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
9251                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9252                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
9253                     persistChanged |= perm.revokeModes(
9254                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION,
9255                             targetPackage == null);
9256                     if (perm.modeFlags == 0) {
9257                         perms.removeAt(j);
9258                     }
9259                 }
9260             }
9261
9262             if (perms.isEmpty()) {
9263                 mGrantedUriPermissions.removeAt(i);
9264             }
9265         }
9266
9267         if (persistChanged) {
9268             schedulePersistUriGrants();
9269         }
9270     }
9271
9272     /**
9273      * @param uri This uri must NOT contain an embedded userId.
9274      * @param userId The userId in which the uri is to be resolved.
9275      */
9276     @Override
9277     public void revokeUriPermission(IApplicationThread caller, String targetPackage, Uri uri,
9278             final int modeFlags, int userId) {
9279         enforceNotIsolatedCaller("revokeUriPermission");
9280         synchronized(this) {
9281             final ProcessRecord r = getRecordForAppLocked(caller);
9282             if (r == null) {
9283                 throw new SecurityException("Unable to find app for caller "
9284                         + caller
9285                         + " when revoking permission to uri " + uri);
9286             }
9287             if (uri == null) {
9288                 Slog.w(TAG, "revokeUriPermission: null uri");
9289                 return;
9290             }
9291
9292             if (!Intent.isAccessUriMode(modeFlags)) {
9293                 return;
9294             }
9295
9296             final String authority = uri.getAuthority();
9297             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
9298                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
9299             if (pi == null) {
9300                 Slog.w(TAG, "No content provider found for permission revoke: "
9301                         + uri.toSafeString());
9302                 return;
9303             }
9304
9305             revokeUriPermissionLocked(targetPackage, r.uid, new GrantUri(userId, uri, false),
9306                     modeFlags);
9307         }
9308     }
9309
9310     /**
9311      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
9312      * given package.
9313      *
9314      * @param packageName Package name to match, or {@code null} to apply to all
9315      *            packages.
9316      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
9317      *            to all users.
9318      * @param persistable If persistable grants should be removed.
9319      */
9320     private void removeUriPermissionsForPackageLocked(
9321             String packageName, int userHandle, boolean persistable) {
9322         if (userHandle == UserHandle.USER_ALL && packageName == null) {
9323             throw new IllegalArgumentException("Must narrow by either package or user");
9324         }
9325
9326         boolean persistChanged = false;
9327
9328         int N = mGrantedUriPermissions.size();
9329         for (int i = 0; i < N; i++) {
9330             final int targetUid = mGrantedUriPermissions.keyAt(i);
9331             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9332
9333             // Only inspect grants matching user
9334             if (userHandle == UserHandle.USER_ALL
9335                     || userHandle == UserHandle.getUserId(targetUid)) {
9336                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
9337                     final UriPermission perm = it.next();
9338
9339                     // Only inspect grants matching package
9340                     if (packageName == null || perm.sourcePkg.equals(packageName)
9341                             || perm.targetPkg.equals(packageName)) {
9342                         // Hacky solution as part of fixing a security bug; ignore
9343                         // grants associated with DownloadManager so we don't have
9344                         // to immediately launch it to regrant the permissions
9345                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
9346                                 && !persistable) continue;
9347
9348                         persistChanged |= perm.revokeModes(persistable
9349                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
9350
9351                         // Only remove when no modes remain; any persisted grants
9352                         // will keep this alive.
9353                         if (perm.modeFlags == 0) {
9354                             it.remove();
9355                         }
9356                     }
9357                 }
9358
9359                 if (perms.isEmpty()) {
9360                     mGrantedUriPermissions.remove(targetUid);
9361                     N--;
9362                     i--;
9363                 }
9364             }
9365         }
9366
9367         if (persistChanged) {
9368             schedulePersistUriGrants();
9369         }
9370     }
9371
9372     @Override
9373     public IBinder newUriPermissionOwner(String name) {
9374         enforceNotIsolatedCaller("newUriPermissionOwner");
9375         synchronized(this) {
9376             UriPermissionOwner owner = new UriPermissionOwner(this, name);
9377             return owner.getExternalTokenLocked();
9378         }
9379     }
9380
9381     @Override
9382     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
9383         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
9384         synchronized(this) {
9385             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9386             if (r == null) {
9387                 throw new IllegalArgumentException("Activity does not exist; token="
9388                         + activityToken);
9389             }
9390             return r.getUriPermissionsLocked().getExternalTokenLocked();
9391         }
9392     }
9393     /**
9394      * @param uri This uri must NOT contain an embedded userId.
9395      * @param sourceUserId The userId in which the uri is to be resolved.
9396      * @param targetUserId The userId of the app that receives the grant.
9397      */
9398     @Override
9399     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
9400             final int modeFlags, int sourceUserId, int targetUserId) {
9401         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
9402                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
9403                 "grantUriPermissionFromOwner", null);
9404         synchronized(this) {
9405             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9406             if (owner == null) {
9407                 throw new IllegalArgumentException("Unknown owner: " + token);
9408             }
9409             if (fromUid != Binder.getCallingUid()) {
9410                 if (Binder.getCallingUid() != myUid()) {
9411                     // Only system code can grant URI permissions on behalf
9412                     // of other users.
9413                     throw new SecurityException("nice try");
9414                 }
9415             }
9416             if (targetPkg == null) {
9417                 throw new IllegalArgumentException("null target");
9418             }
9419             if (uri == null) {
9420                 throw new IllegalArgumentException("null uri");
9421             }
9422
9423             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
9424                     modeFlags, owner, targetUserId);
9425         }
9426     }
9427
9428     /**
9429      * @param uri This uri must NOT contain an embedded userId.
9430      * @param userId The userId in which the uri is to be resolved.
9431      */
9432     @Override
9433     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
9434         synchronized(this) {
9435             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
9436             if (owner == null) {
9437                 throw new IllegalArgumentException("Unknown owner: " + token);
9438             }
9439
9440             if (uri == null) {
9441                 owner.removeUriPermissionsLocked(mode);
9442             } else {
9443                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
9444                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
9445             }
9446         }
9447     }
9448
9449     private void schedulePersistUriGrants() {
9450         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
9451             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
9452                     10 * DateUtils.SECOND_IN_MILLIS);
9453         }
9454     }
9455
9456     private void writeGrantedUriPermissions() {
9457         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
9458
9459         // Snapshot permissions so we can persist without lock
9460         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
9461         synchronized (this) {
9462             final int size = mGrantedUriPermissions.size();
9463             for (int i = 0; i < size; i++) {
9464                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9465                 for (UriPermission perm : perms.values()) {
9466                     if (perm.persistedModeFlags != 0) {
9467                         persist.add(perm.snapshot());
9468                     }
9469                 }
9470             }
9471         }
9472
9473         FileOutputStream fos = null;
9474         try {
9475             fos = mGrantFile.startWrite();
9476
9477             XmlSerializer out = new FastXmlSerializer();
9478             out.setOutput(fos, StandardCharsets.UTF_8.name());
9479             out.startDocument(null, true);
9480             out.startTag(null, TAG_URI_GRANTS);
9481             for (UriPermission.Snapshot perm : persist) {
9482                 out.startTag(null, TAG_URI_GRANT);
9483                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
9484                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
9485                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
9486                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
9487                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
9488                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
9489                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
9490                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
9491                 out.endTag(null, TAG_URI_GRANT);
9492             }
9493             out.endTag(null, TAG_URI_GRANTS);
9494             out.endDocument();
9495
9496             mGrantFile.finishWrite(fos);
9497         } catch (IOException e) {
9498             if (fos != null) {
9499                 mGrantFile.failWrite(fos);
9500             }
9501         }
9502     }
9503
9504     private void readGrantedUriPermissionsLocked() {
9505         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
9506
9507         final long now = System.currentTimeMillis();
9508
9509         FileInputStream fis = null;
9510         try {
9511             fis = mGrantFile.openRead();
9512             final XmlPullParser in = Xml.newPullParser();
9513             in.setInput(fis, StandardCharsets.UTF_8.name());
9514
9515             int type;
9516             while ((type = in.next()) != END_DOCUMENT) {
9517                 final String tag = in.getName();
9518                 if (type == START_TAG) {
9519                     if (TAG_URI_GRANT.equals(tag)) {
9520                         final int sourceUserId;
9521                         final int targetUserId;
9522                         final int userHandle = readIntAttribute(in,
9523                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
9524                         if (userHandle != UserHandle.USER_NULL) {
9525                             // For backwards compatibility.
9526                             sourceUserId = userHandle;
9527                             targetUserId = userHandle;
9528                         } else {
9529                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
9530                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
9531                         }
9532                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
9533                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
9534                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
9535                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
9536                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
9537                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
9538
9539                         // Sanity check that provider still belongs to source package
9540                         // Both direct boot aware and unaware packages are fine as we
9541                         // will do filtering at query time to avoid multiple parsing.
9542                         final ProviderInfo pi = getProviderInfoLocked(
9543                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
9544                                         | MATCH_DIRECT_BOOT_UNAWARE);
9545                         if (pi != null && sourcePkg.equals(pi.packageName)) {
9546                             int targetUid = -1;
9547                             try {
9548                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
9549                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
9550                             } catch (RemoteException e) {
9551                             }
9552                             if (targetUid != -1) {
9553                                 final UriPermission perm = findOrCreateUriPermissionLocked(
9554                                         sourcePkg, targetPkg, targetUid,
9555                                         new GrantUri(sourceUserId, uri, prefix));
9556                                 perm.initPersistedModes(modeFlags, createdTime);
9557                             }
9558                         } else {
9559                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
9560                                     + " but instead found " + pi);
9561                         }
9562                     }
9563                 }
9564             }
9565         } catch (FileNotFoundException e) {
9566             // Missing grants is okay
9567         } catch (IOException e) {
9568             Slog.wtf(TAG, "Failed reading Uri grants", e);
9569         } catch (XmlPullParserException e) {
9570             Slog.wtf(TAG, "Failed reading Uri grants", e);
9571         } finally {
9572             IoUtils.closeQuietly(fis);
9573         }
9574     }
9575
9576     /**
9577      * @param uri This uri must NOT contain an embedded userId.
9578      * @param userId The userId in which the uri is to be resolved.
9579      */
9580     @Override
9581     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9582         enforceNotIsolatedCaller("takePersistableUriPermission");
9583
9584         Preconditions.checkFlagsArgument(modeFlags,
9585                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9586
9587         synchronized (this) {
9588             final int callingUid = Binder.getCallingUid();
9589             boolean persistChanged = false;
9590             GrantUri grantUri = new GrantUri(userId, uri, false);
9591
9592             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9593                     new GrantUri(userId, uri, false));
9594             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9595                     new GrantUri(userId, uri, true));
9596
9597             final boolean exactValid = (exactPerm != null)
9598                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
9599             final boolean prefixValid = (prefixPerm != null)
9600                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
9601
9602             if (!(exactValid || prefixValid)) {
9603                 throw new SecurityException("No persistable permission grants found for UID "
9604                         + callingUid + " and Uri " + grantUri.toSafeString());
9605             }
9606
9607             if (exactValid) {
9608                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
9609             }
9610             if (prefixValid) {
9611                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
9612             }
9613
9614             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
9615
9616             if (persistChanged) {
9617                 schedulePersistUriGrants();
9618             }
9619         }
9620     }
9621
9622     /**
9623      * @param uri This uri must NOT contain an embedded userId.
9624      * @param userId The userId in which the uri is to be resolved.
9625      */
9626     @Override
9627     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
9628         enforceNotIsolatedCaller("releasePersistableUriPermission");
9629
9630         Preconditions.checkFlagsArgument(modeFlags,
9631                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
9632
9633         synchronized (this) {
9634             final int callingUid = Binder.getCallingUid();
9635             boolean persistChanged = false;
9636
9637             UriPermission exactPerm = findUriPermissionLocked(callingUid,
9638                     new GrantUri(userId, uri, false));
9639             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
9640                     new GrantUri(userId, uri, true));
9641             if (exactPerm == null && prefixPerm == null) {
9642                 throw new SecurityException("No permission grants found for UID " + callingUid
9643                         + " and Uri " + uri.toSafeString());
9644             }
9645
9646             if (exactPerm != null) {
9647                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
9648                 removeUriPermissionIfNeededLocked(exactPerm);
9649             }
9650             if (prefixPerm != null) {
9651                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
9652                 removeUriPermissionIfNeededLocked(prefixPerm);
9653             }
9654
9655             if (persistChanged) {
9656                 schedulePersistUriGrants();
9657             }
9658         }
9659     }
9660
9661     /**
9662      * Prune any older {@link UriPermission} for the given UID until outstanding
9663      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
9664      *
9665      * @return if any mutations occured that require persisting.
9666      */
9667     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
9668         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
9669         if (perms == null) return false;
9670         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
9671
9672         final ArrayList<UriPermission> persisted = Lists.newArrayList();
9673         for (UriPermission perm : perms.values()) {
9674             if (perm.persistedModeFlags != 0) {
9675                 persisted.add(perm);
9676             }
9677         }
9678
9679         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
9680         if (trimCount <= 0) return false;
9681
9682         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
9683         for (int i = 0; i < trimCount; i++) {
9684             final UriPermission perm = persisted.get(i);
9685
9686             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
9687                     "Trimming grant created at " + perm.persistedCreateTime);
9688
9689             perm.releasePersistableModes(~0);
9690             removeUriPermissionIfNeededLocked(perm);
9691         }
9692
9693         return true;
9694     }
9695
9696     @Override
9697     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
9698             String packageName, boolean incoming) {
9699         enforceNotIsolatedCaller("getPersistedUriPermissions");
9700         Preconditions.checkNotNull(packageName, "packageName");
9701
9702         final int callingUid = Binder.getCallingUid();
9703         final int callingUserId = UserHandle.getUserId(callingUid);
9704         final IPackageManager pm = AppGlobals.getPackageManager();
9705         try {
9706             final int packageUid = pm.getPackageUid(packageName,
9707                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
9708             if (packageUid != callingUid) {
9709                 throw new SecurityException(
9710                         "Package " + packageName + " does not belong to calling UID " + callingUid);
9711             }
9712         } catch (RemoteException e) {
9713             throw new SecurityException("Failed to verify package name ownership");
9714         }
9715
9716         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9717         synchronized (this) {
9718             if (incoming) {
9719                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
9720                         callingUid);
9721                 if (perms == null) {
9722                     Slog.w(TAG, "No permission grants found for " + packageName);
9723                 } else {
9724                     for (UriPermission perm : perms.values()) {
9725                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
9726                             result.add(perm.buildPersistedPublicApiObject());
9727                         }
9728                     }
9729                 }
9730             } else {
9731                 final int size = mGrantedUriPermissions.size();
9732                 for (int i = 0; i < size; i++) {
9733                     final ArrayMap<GrantUri, UriPermission> perms =
9734                             mGrantedUriPermissions.valueAt(i);
9735                     for (UriPermission perm : perms.values()) {
9736                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
9737                             result.add(perm.buildPersistedPublicApiObject());
9738                         }
9739                     }
9740                 }
9741             }
9742         }
9743         return new ParceledListSlice<android.content.UriPermission>(result);
9744     }
9745
9746     @Override
9747     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
9748             String packageName, int userId) {
9749         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
9750                 "getGrantedUriPermissions");
9751
9752         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
9753         synchronized (this) {
9754             final int size = mGrantedUriPermissions.size();
9755             for (int i = 0; i < size; i++) {
9756                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
9757                 for (UriPermission perm : perms.values()) {
9758                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9759                             && perm.persistedModeFlags != 0) {
9760                         result.add(perm.buildPersistedPublicApiObject());
9761                     }
9762                 }
9763             }
9764         }
9765         return new ParceledListSlice<android.content.UriPermission>(result);
9766     }
9767
9768     @Override
9769     public void clearGrantedUriPermissions(String packageName, int userId) {
9770         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9771                 "clearGrantedUriPermissions");
9772         removeUriPermissionsForPackageLocked(packageName, userId, true);
9773     }
9774
9775     @Override
9776     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9777         synchronized (this) {
9778             ProcessRecord app =
9779                 who != null ? getRecordForAppLocked(who) : null;
9780             if (app == null) return;
9781
9782             Message msg = Message.obtain();
9783             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9784             msg.obj = app;
9785             msg.arg1 = waiting ? 1 : 0;
9786             mUiHandler.sendMessage(msg);
9787         }
9788     }
9789
9790     @Override
9791     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9792         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9793         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9794         outInfo.availMem = getFreeMemory();
9795         outInfo.totalMem = getTotalMemory();
9796         outInfo.threshold = homeAppMem;
9797         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9798         outInfo.hiddenAppThreshold = cachedAppMem;
9799         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9800                 ProcessList.SERVICE_ADJ);
9801         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9802                 ProcessList.VISIBLE_APP_ADJ);
9803         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9804                 ProcessList.FOREGROUND_APP_ADJ);
9805     }
9806
9807     // =========================================================
9808     // TASK MANAGEMENT
9809     // =========================================================
9810
9811     @Override
9812     public List<IBinder> getAppTasks(String callingPackage) {
9813         int callingUid = Binder.getCallingUid();
9814         long ident = Binder.clearCallingIdentity();
9815
9816         synchronized(this) {
9817             ArrayList<IBinder> list = new ArrayList<IBinder>();
9818             try {
9819                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9820
9821                 final int N = mRecentTasks.size();
9822                 for (int i = 0; i < N; i++) {
9823                     TaskRecord tr = mRecentTasks.get(i);
9824                     // Skip tasks that do not match the caller.  We don't need to verify
9825                     // callingPackage, because we are also limiting to callingUid and know
9826                     // that will limit to the correct security sandbox.
9827                     if (tr.effectiveUid != callingUid) {
9828                         continue;
9829                     }
9830                     Intent intent = tr.getBaseIntent();
9831                     if (intent == null ||
9832                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9833                         continue;
9834                     }
9835                     ActivityManager.RecentTaskInfo taskInfo =
9836                             createRecentTaskInfoFromTaskRecord(tr);
9837                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9838                     list.add(taskImpl.asBinder());
9839                 }
9840             } finally {
9841                 Binder.restoreCallingIdentity(ident);
9842             }
9843             return list;
9844         }
9845     }
9846
9847     @Override
9848     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9849         final int callingUid = Binder.getCallingUid();
9850         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9851
9852         synchronized(this) {
9853             if (DEBUG_ALL) Slog.v(
9854                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9855
9856             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9857                     callingUid);
9858
9859             // TODO: Improve with MRU list from all ActivityStacks.
9860             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9861         }
9862
9863         return list;
9864     }
9865
9866     /**
9867      * Creates a new RecentTaskInfo from a TaskRecord.
9868      */
9869     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9870         // Update the task description to reflect any changes in the task stack
9871         tr.updateTaskDescription();
9872
9873         // Compose the recent task info
9874         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9875         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9876         rti.persistentId = tr.taskId;
9877         rti.baseIntent = new Intent(tr.getBaseIntent());
9878         rti.origActivity = tr.origActivity;
9879         rti.realActivity = tr.realActivity;
9880         rti.description = tr.lastDescription;
9881         rti.stackId = tr.getStackId();
9882         rti.userId = tr.userId;
9883         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9884         rti.firstActiveTime = tr.firstActiveTime;
9885         rti.lastActiveTime = tr.lastActiveTime;
9886         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9887         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9888         rti.numActivities = 0;
9889         if (tr.mBounds != null) {
9890             rti.bounds = new Rect(tr.mBounds);
9891         }
9892         rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreen();
9893         rti.resizeMode = tr.mResizeMode;
9894
9895         ActivityRecord base = null;
9896         ActivityRecord top = null;
9897         ActivityRecord tmp;
9898
9899         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9900             tmp = tr.mActivities.get(i);
9901             if (tmp.finishing) {
9902                 continue;
9903             }
9904             base = tmp;
9905             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9906                 top = base;
9907             }
9908             rti.numActivities++;
9909         }
9910
9911         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9912         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9913
9914         return rti;
9915     }
9916
9917     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9918         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9919                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9920         if (!allowed) {
9921             if (checkPermission(android.Manifest.permission.GET_TASKS,
9922                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9923                 // Temporary compatibility: some existing apps on the system image may
9924                 // still be requesting the old permission and not switched to the new
9925                 // one; if so, we'll still allow them full access.  This means we need
9926                 // to see if they are holding the old permission and are a system app.
9927                 try {
9928                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9929                         allowed = true;
9930                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9931                                 + " is using old GET_TASKS but privileged; allowing");
9932                     }
9933                 } catch (RemoteException e) {
9934                 }
9935             }
9936         }
9937         if (!allowed) {
9938             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9939                     + " does not hold REAL_GET_TASKS; limiting output");
9940         }
9941         return allowed;
9942     }
9943
9944     @Override
9945     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9946             int userId) {
9947         final int callingUid = Binder.getCallingUid();
9948         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9949                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9950
9951         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9952         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9953         synchronized (this) {
9954             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9955                     callingUid);
9956             final boolean detailed = checkCallingPermission(
9957                     android.Manifest.permission.GET_DETAILED_TASKS)
9958                     == PackageManager.PERMISSION_GRANTED;
9959
9960             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9961                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9962                 return ParceledListSlice.emptyList();
9963             }
9964             mRecentTasks.loadUserRecentsLocked(userId);
9965
9966             final int recentsCount = mRecentTasks.size();
9967             ArrayList<ActivityManager.RecentTaskInfo> res =
9968                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9969
9970             final Set<Integer> includedUsers;
9971             if (includeProfiles) {
9972                 includedUsers = mUserController.getProfileIds(userId);
9973             } else {
9974                 includedUsers = new HashSet<>();
9975             }
9976             includedUsers.add(Integer.valueOf(userId));
9977
9978             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9979                 TaskRecord tr = mRecentTasks.get(i);
9980                 // Only add calling user or related users recent tasks
9981                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9982                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9983                     continue;
9984                 }
9985
9986                 if (tr.realActivitySuspended) {
9987                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9988                     continue;
9989                 }
9990
9991                 // Return the entry if desired by the caller.  We always return
9992                 // the first entry, because callers always expect this to be the
9993                 // foreground app.  We may filter others if the caller has
9994                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9995                 // we should exclude the entry.
9996
9997                 if (i == 0
9998                         || withExcluded
9999                         || (tr.intent == null)
10000                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
10001                                 == 0)) {
10002                     if (!allowed) {
10003                         // If the caller doesn't have the GET_TASKS permission, then only
10004                         // allow them to see a small subset of tasks -- their own and home.
10005                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
10006                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
10007                             continue;
10008                         }
10009                     }
10010                     final ActivityStack stack = tr.getStack();
10011                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS) != 0) {
10012                         if (stack != null && stack.isHomeOrRecentsStack()) {
10013                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10014                                     "Skipping, home or recents stack task: " + tr);
10015                             continue;
10016                         }
10017                     }
10018                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
10019                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
10020                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10021                                     "Skipping, top task in docked stack: " + tr);
10022                             continue;
10023                         }
10024                     }
10025                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
10026                         if (stack != null && stack.isPinnedStack()) {
10027                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10028                                     "Skipping, pinned stack task: " + tr);
10029                             continue;
10030                         }
10031                     }
10032                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
10033                         // Don't include auto remove tasks that are finished or finishing.
10034                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10035                                 "Skipping, auto-remove without activity: " + tr);
10036                         continue;
10037                     }
10038                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
10039                             && !tr.isAvailable) {
10040                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10041                                 "Skipping, unavail real act: " + tr);
10042                         continue;
10043                     }
10044
10045                     if (!tr.mUserSetupComplete) {
10046                         // Don't include task launched while user is not done setting-up.
10047                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
10048                                 "Skipping, user setup not complete: " + tr);
10049                         continue;
10050                     }
10051
10052                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
10053                     if (!detailed) {
10054                         rti.baseIntent.replaceExtras((Bundle)null);
10055                     }
10056
10057                     res.add(rti);
10058                     maxNum--;
10059                 }
10060             }
10061             return new ParceledListSlice<>(res);
10062         }
10063     }
10064
10065     @Override
10066     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
10067         synchronized (this) {
10068             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
10069                     "getTaskThumbnail()");
10070             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10071                     id, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10072             if (tr != null) {
10073                 return tr.getTaskThumbnailLocked();
10074             }
10075         }
10076         return null;
10077     }
10078
10079     @Override
10080     public ActivityManager.TaskDescription getTaskDescription(int id) {
10081         synchronized (this) {
10082             enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10083                     "getTaskDescription()");
10084             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id,
10085                     MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10086             if (tr != null) {
10087                 return tr.lastTaskDescription;
10088             }
10089         }
10090         return null;
10091     }
10092
10093     @Override
10094     public int addAppTask(IBinder activityToken, Intent intent,
10095             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
10096         final int callingUid = Binder.getCallingUid();
10097         final long callingIdent = Binder.clearCallingIdentity();
10098
10099         try {
10100             synchronized (this) {
10101                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
10102                 if (r == null) {
10103                     throw new IllegalArgumentException("Activity does not exist; token="
10104                             + activityToken);
10105                 }
10106                 ComponentName comp = intent.getComponent();
10107                 if (comp == null) {
10108                     throw new IllegalArgumentException("Intent " + intent
10109                             + " must specify explicit component");
10110                 }
10111                 if (thumbnail.getWidth() != mThumbnailWidth
10112                         || thumbnail.getHeight() != mThumbnailHeight) {
10113                     throw new IllegalArgumentException("Bad thumbnail size: got "
10114                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
10115                             + mThumbnailWidth + "x" + mThumbnailHeight);
10116                 }
10117                 if (intent.getSelector() != null) {
10118                     intent.setSelector(null);
10119                 }
10120                 if (intent.getSourceBounds() != null) {
10121                     intent.setSourceBounds(null);
10122                 }
10123                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
10124                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
10125                         // The caller has added this as an auto-remove task...  that makes no
10126                         // sense, so turn off auto-remove.
10127                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
10128                     }
10129                 }
10130                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
10131                     mLastAddedTaskActivity = null;
10132                 }
10133                 ActivityInfo ainfo = mLastAddedTaskActivity;
10134                 if (ainfo == null) {
10135                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
10136                             comp, 0, UserHandle.getUserId(callingUid));
10137                     if (ainfo.applicationInfo.uid != callingUid) {
10138                         throw new SecurityException(
10139                                 "Can't add task for another application: target uid="
10140                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
10141                     }
10142                 }
10143
10144                 TaskRecord task = new TaskRecord(this,
10145                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
10146                         ainfo, intent, description, new TaskThumbnailInfo());
10147
10148                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
10149                 if (trimIdx >= 0) {
10150                     // If this would have caused a trim, then we'll abort because that
10151                     // means it would be added at the end of the list but then just removed.
10152                     return INVALID_TASK_ID;
10153                 }
10154
10155                 final int N = mRecentTasks.size();
10156                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
10157                     final TaskRecord tr = mRecentTasks.remove(N - 1);
10158                     tr.removedFromRecents();
10159                 }
10160
10161                 task.inRecents = true;
10162                 mRecentTasks.add(task);
10163                 r.getStack().addTask(task, false, "addAppTask");
10164
10165                 task.setLastThumbnailLocked(thumbnail);
10166                 task.freeLastThumbnail();
10167                 return task.taskId;
10168             }
10169         } finally {
10170             Binder.restoreCallingIdentity(callingIdent);
10171         }
10172     }
10173
10174     @Override
10175     public Point getAppTaskThumbnailSize() {
10176         synchronized (this) {
10177             return new Point(mThumbnailWidth,  mThumbnailHeight);
10178         }
10179     }
10180
10181     @Override
10182     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
10183         synchronized (this) {
10184             ActivityRecord r = ActivityRecord.isInStackLocked(token);
10185             if (r != null) {
10186                 r.setTaskDescription(td);
10187                 final TaskRecord task = r.getTask();
10188                 task.updateTaskDescription();
10189                 mTaskChangeNotificationController.notifyTaskDescriptionChanged(task.taskId, td);
10190             }
10191         }
10192     }
10193
10194     @Override
10195     public void setTaskResizeable(int taskId, int resizeableMode) {
10196         synchronized (this) {
10197             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
10198                     taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10199             if (task == null) {
10200                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
10201                 return;
10202             }
10203             task.setResizeMode(resizeableMode);
10204         }
10205     }
10206
10207     @Override
10208     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
10209         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
10210         long ident = Binder.clearCallingIdentity();
10211         try {
10212             synchronized (this) {
10213                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10214                 if (task == null) {
10215                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
10216                     return;
10217                 }
10218                 // Place the task in the right stack if it isn't there already based on
10219                 // the requested bounds.
10220                 // The stack transition logic is:
10221                 // - a null bounds on a freeform task moves that task to fullscreen
10222                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
10223                 //   that task to freeform
10224                 // - otherwise the task is not moved
10225                 int stackId = task.getStackId();
10226                 if (!StackId.isTaskResizeAllowed(stackId)) {
10227                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
10228                 }
10229                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
10230                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
10231                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
10232                     stackId = FREEFORM_WORKSPACE_STACK_ID;
10233                 }
10234
10235                 // Reparent the task to the right stack if necessary
10236                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
10237                 if (stackId != task.getStackId()) {
10238                     // Defer resume until the task is resized below
10239                     task.reparent(stackId, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10240                             DEFER_RESUME, "resizeTask");
10241                     preserveWindow = false;
10242                 }
10243
10244                 // After reparenting (which only resizes the task to the stack bounds), resize the
10245                 // task to the actual bounds provided
10246                 task.resize(bounds, resizeMode, preserveWindow, !DEFER_RESUME);
10247             }
10248         } finally {
10249             Binder.restoreCallingIdentity(ident);
10250         }
10251     }
10252
10253     @Override
10254     public Rect getTaskBounds(int taskId) {
10255         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
10256         long ident = Binder.clearCallingIdentity();
10257         Rect rect = new Rect();
10258         try {
10259             synchronized (this) {
10260                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10261                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10262                 if (task == null) {
10263                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
10264                     return rect;
10265                 }
10266                 if (task.getStack() != null) {
10267                     // Return the bounds from window manager since it will be adjusted for various
10268                     // things like the presense of a docked stack for tasks that aren't resizeable.
10269                     task.getWindowContainerBounds(rect);
10270                 } else {
10271                     // Task isn't in window manager yet since it isn't associated with a stack.
10272                     // Return the persist value from activity manager
10273                     if (task.mBounds != null) {
10274                         rect.set(task.mBounds);
10275                     } else if (task.mLastNonFullscreenBounds != null) {
10276                         rect.set(task.mLastNonFullscreenBounds);
10277                     }
10278                 }
10279             }
10280         } finally {
10281             Binder.restoreCallingIdentity(ident);
10282         }
10283         return rect;
10284     }
10285
10286     @Override
10287     public void cancelTaskWindowTransition(int taskId) {
10288         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskWindowTransition()");
10289         final long ident = Binder.clearCallingIdentity();
10290         try {
10291             synchronized (this) {
10292                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10293                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10294                 if (task == null) {
10295                     Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
10296                     return;
10297                 }
10298                 task.cancelWindowTransition();
10299             }
10300         } finally {
10301             Binder.restoreCallingIdentity(ident);
10302         }
10303     }
10304
10305     @Override
10306     public void cancelTaskThumbnailTransition(int taskId) {
10307         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "cancelTaskThumbnailTransition()");
10308         final long ident = Binder.clearCallingIdentity();
10309         try {
10310             synchronized (this) {
10311                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId,
10312                         MATCH_TASK_IN_STACKS_ONLY, INVALID_STACK_ID);
10313                 if (task == null) {
10314                     Slog.w(TAG, "cancelTaskThumbnailTransition: taskId=" + taskId + " not found");
10315                     return;
10316                 }
10317                 task.cancelThumbnailTransition();
10318             }
10319         } finally {
10320             Binder.restoreCallingIdentity(ident);
10321         }
10322     }
10323
10324     @Override
10325     public TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution) {
10326         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
10327         final long ident = Binder.clearCallingIdentity();
10328         try {
10329             final TaskRecord task;
10330             synchronized (this) {
10331                 task = mStackSupervisor.anyTaskForIdLocked(taskId,
10332                         MATCH_TASK_IN_STACKS_OR_RECENT_TASKS, INVALID_STACK_ID);
10333                 if (task == null) {
10334                     Slog.w(TAG, "getTaskSnapshot: taskId=" + taskId + " not found");
10335                     return null;
10336                 }
10337             }
10338             // Don't call this while holding the lock as this operation might hit the disk.
10339             return task.getSnapshot(reducedResolution);
10340         } finally {
10341             Binder.restoreCallingIdentity(ident);
10342         }
10343     }
10344
10345     @Override
10346     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
10347         if (userId != UserHandle.getCallingUserId()) {
10348             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10349                     "getTaskDescriptionIcon");
10350         }
10351         final File passedIconFile = new File(filePath);
10352         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
10353                 passedIconFile.getName());
10354         if (!legitIconFile.getPath().equals(filePath)
10355                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
10356             throw new IllegalArgumentException("Bad file path: " + filePath
10357                     + " passed for userId " + userId);
10358         }
10359         return mRecentTasks.getTaskDescriptionIcon(filePath);
10360     }
10361
10362     @Override
10363     public void startInPlaceAnimationOnFrontMostApplication(Bundle opts)
10364             throws RemoteException {
10365         final ActivityOptions activityOptions = ActivityOptions.fromBundle(opts);
10366         if (activityOptions.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
10367                 activityOptions.getCustomInPlaceResId() == 0) {
10368             throw new IllegalArgumentException("Expected in-place ActivityOption " +
10369                     "with valid animation");
10370         }
10371         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
10372         mWindowManager.overridePendingAppTransitionInPlace(activityOptions.getPackageName(),
10373                 activityOptions.getCustomInPlaceResId());
10374         mWindowManager.executeAppTransition();
10375     }
10376
10377     private void removeTasksByPackageNameLocked(String packageName, int userId) {
10378         // Remove all tasks with activities in the specified package from the list of recent tasks
10379         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10380             TaskRecord tr = mRecentTasks.get(i);
10381             if (tr.userId != userId) continue;
10382
10383             ComponentName cn = tr.intent.getComponent();
10384             if (cn != null && cn.getPackageName().equals(packageName)) {
10385                 // If the package name matches, remove the task.
10386                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
10387             }
10388         }
10389     }
10390
10391     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
10392             int userId) {
10393
10394         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
10395             TaskRecord tr = mRecentTasks.get(i);
10396             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
10397                 continue;
10398             }
10399
10400             ComponentName cn = tr.intent.getComponent();
10401             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
10402                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
10403             if (sameComponent) {
10404                 mStackSupervisor.removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
10405             }
10406         }
10407     }
10408
10409     @Override
10410     public void removeStack(int stackId) {
10411         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
10412         if (StackId.isHomeOrRecentsStack(stackId)) {
10413             throw new IllegalArgumentException("Removing home or recents stack is not allowed.");
10414         }
10415
10416         synchronized (this) {
10417             final long ident = Binder.clearCallingIdentity();
10418             try {
10419                 mStackSupervisor.removeStackLocked(stackId);
10420             } finally {
10421                 Binder.restoreCallingIdentity(ident);
10422             }
10423         }
10424     }
10425
10426     @Override
10427     public void moveStackToDisplay(int stackId, int displayId) {
10428         enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
10429
10430         synchronized (this) {
10431             final long ident = Binder.clearCallingIdentity();
10432             try {
10433                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveStackToDisplay: moving stackId=" + stackId
10434                         + " to displayId=" + displayId);
10435                 mStackSupervisor.moveStackToDisplayLocked(stackId, displayId, ON_TOP);
10436             } finally {
10437                 Binder.restoreCallingIdentity(ident);
10438             }
10439         }
10440     }
10441
10442     @Override
10443     public boolean removeTask(int taskId) {
10444         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
10445         synchronized (this) {
10446             final long ident = Binder.clearCallingIdentity();
10447             try {
10448                 return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
10449             } finally {
10450                 Binder.restoreCallingIdentity(ident);
10451             }
10452         }
10453     }
10454
10455     /**
10456      * TODO: Add mController hook
10457      */
10458     @Override
10459     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
10460         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
10461
10462         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
10463         synchronized(this) {
10464             moveTaskToFrontLocked(taskId, flags, bOptions, false /* fromRecents */);
10465         }
10466     }
10467
10468     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions, boolean fromRecents) {
10469         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
10470
10471         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10472                 Binder.getCallingUid(), -1, -1, "Task to front")) {
10473             ActivityOptions.abort(options);
10474             return;
10475         }
10476         final long origId = Binder.clearCallingIdentity();
10477         try {
10478             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10479             if (task == null) {
10480                 Slog.d(TAG, "Could not find task for id: "+ taskId);
10481                 return;
10482             }
10483             if (mStackSupervisor.isLockTaskModeViolation(task)) {
10484                 mStackSupervisor.showLockTaskToast();
10485                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
10486                 return;
10487             }
10488             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
10489             if (prev != null) {
10490                 task.setTaskToReturnTo(prev);
10491             }
10492             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
10493                     false /* forceNonResizable */);
10494
10495             final ActivityRecord topActivity = task.getTopActivity();
10496             if (topActivity != null) {
10497
10498                 // We are reshowing a task, use a starting window to hide the initial draw delay
10499                 // so the transition can start earlier.
10500                 topActivity.showStartingWindow(null /* prev */, false /* newTask */,
10501                         true /* taskSwitch */, fromRecents);
10502             }
10503         } finally {
10504             Binder.restoreCallingIdentity(origId);
10505         }
10506         ActivityOptions.abort(options);
10507     }
10508
10509     /**
10510      * Attempts to move a task backwards in z-order (the order of activities within the task is
10511      * unchanged).
10512      *
10513      * There are several possible results of this call:
10514      * - if the task is locked, then we will show the lock toast
10515      * - if there is a task behind the provided task, then that task is made visible and resumed as
10516      *   this task is moved to the back
10517      * - otherwise, if there are no other tasks in the stack:
10518      *     - if this task is in the pinned stack, then we remove the stack completely, which will
10519      *       have the effect of moving the task to the top or bottom of the fullscreen stack
10520      *       (depending on whether it is visible)
10521      *     - otherwise, we simply return home and hide this task
10522      *
10523      * @param token A reference to the activity we wish to move
10524      * @param nonRoot If false then this only works if the activity is the root
10525      *                of a task; if true it will work for any activity in a task.
10526      * @return Returns true if the move completed, false if not.
10527      */
10528     @Override
10529     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
10530         enforceNotIsolatedCaller("moveActivityTaskToBack");
10531         synchronized(this) {
10532             final long origId = Binder.clearCallingIdentity();
10533             try {
10534                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
10535                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10536                 if (task != null) {
10537                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
10538                 }
10539             } finally {
10540                 Binder.restoreCallingIdentity(origId);
10541             }
10542         }
10543         return false;
10544     }
10545
10546     @Override
10547     public void moveTaskBackwards(int task) {
10548         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
10549                 "moveTaskBackwards()");
10550
10551         synchronized(this) {
10552             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
10553                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
10554                 return;
10555             }
10556             final long origId = Binder.clearCallingIdentity();
10557             moveTaskBackwardsLocked(task);
10558             Binder.restoreCallingIdentity(origId);
10559         }
10560     }
10561
10562     private final void moveTaskBackwardsLocked(int task) {
10563         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
10564     }
10565
10566     @Override
10567     public int createStackOnDisplay(int displayId) throws RemoteException {
10568         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
10569         synchronized (this) {
10570             final int stackId = mStackSupervisor.getNextStackId();
10571             final ActivityStack stack =
10572                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
10573             if (stack == null) {
10574                 return INVALID_STACK_ID;
10575             }
10576             return stack.mStackId;
10577         }
10578     }
10579
10580     @Override
10581     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
10582         synchronized (this) {
10583             final ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
10584             if (stack != null && stack.mDisplayId != INVALID_DISPLAY) {
10585                 return stack.mDisplayId;
10586             }
10587             return DEFAULT_DISPLAY;
10588         }
10589     }
10590
10591     @Override
10592     public int getActivityStackId(IBinder token) throws RemoteException {
10593         synchronized (this) {
10594             ActivityStack stack = ActivityRecord.getStackLocked(token);
10595             if (stack == null) {
10596                 return INVALID_STACK_ID;
10597             }
10598             return stack.mStackId;
10599         }
10600     }
10601
10602     @Override
10603     public void exitFreeformMode(IBinder token) throws RemoteException {
10604         synchronized (this) {
10605             long ident = Binder.clearCallingIdentity();
10606             try {
10607                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10608                 if (r == null) {
10609                     throw new IllegalArgumentException(
10610                             "exitFreeformMode: No activity record matching token=" + token);
10611                 }
10612
10613                 final ActivityStack stack = r.getStack();
10614                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
10615                     throw new IllegalStateException(
10616                             "exitFreeformMode: You can only go fullscreen from freeform.");
10617                 }
10618
10619                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
10620                 r.getTask().reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10621                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "exitFreeformMode");
10622             } finally {
10623                 Binder.restoreCallingIdentity(ident);
10624             }
10625         }
10626     }
10627
10628     @Override
10629     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
10630         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
10631         if (StackId.isHomeOrRecentsStack(stackId)) {
10632             throw new IllegalArgumentException(
10633                     "moveTaskToStack: Attempt to move task " + taskId + " to stack " + stackId);
10634         }
10635         synchronized (this) {
10636             long ident = Binder.clearCallingIdentity();
10637             try {
10638                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10639                 if (task == null) {
10640                     Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId);
10641                     return;
10642                 }
10643
10644                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
10645                         + " to stackId=" + stackId + " toTop=" + toTop);
10646                 if (stackId == DOCKED_STACK_ID) {
10647                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
10648                             null /* initialBounds */);
10649                 }
10650                 task.reparent(stackId, toTop,
10651                         REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, "moveTaskToStack");
10652             } finally {
10653                 Binder.restoreCallingIdentity(ident);
10654             }
10655         }
10656     }
10657
10658     @Override
10659     public void swapDockedAndFullscreenStack() throws RemoteException {
10660         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
10661         synchronized (this) {
10662             long ident = Binder.clearCallingIdentity();
10663             try {
10664                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
10665                         FULLSCREEN_WORKSPACE_STACK_ID);
10666                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
10667                         : null;
10668                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
10669                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
10670                         : null;
10671                 if (topTask == null || tasks == null || tasks.size() == 0) {
10672                     Slog.w(TAG,
10673                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
10674                     return;
10675                 }
10676
10677                 // TODO: App transition
10678                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
10679
10680                 // Defer the resume until we move all the docked tasks to the fullscreen stack below
10681                 topTask.reparent(DOCKED_STACK_ID, ON_TOP, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE,
10682                         DEFER_RESUME, "swapDockedAndFullscreenStack - DOCKED_STACK");
10683                 final int size = tasks.size();
10684                 for (int i = 0; i < size; i++) {
10685                     final int id = tasks.get(i).taskId;
10686                     if (id == topTask.taskId) {
10687                         continue;
10688                     }
10689
10690                     // Defer the resume until after all the tasks have been moved
10691                     tasks.get(i).reparent(FULLSCREEN_WORKSPACE_STACK_ID, ON_TOP,
10692                             REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, DEFER_RESUME,
10693                             "swapDockedAndFullscreenStack - FULLSCREEN_STACK");
10694                 }
10695
10696                 // Because we deferred the resume to avoid conflicts with stack switches while
10697                 // resuming, we need to do it after all the tasks are moved.
10698                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10699                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
10700
10701                 mWindowManager.executeAppTransition();
10702             } finally {
10703                 Binder.restoreCallingIdentity(ident);
10704             }
10705         }
10706     }
10707
10708     /**
10709      * Moves the input task to the docked stack.
10710      *
10711      * @param taskId Id of task to move.
10712      * @param createMode The mode the docked stack should be created in if it doesn't exist
10713      *                   already. See
10714      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
10715      *                   and
10716      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
10717      * @param toTop If the task and stack should be moved to the top.
10718      * @param animate Whether we should play an animation for the moving the task
10719      * @param initialBounds If the docked stack gets created, it will use these bounds for the
10720      *                      docked stack. Pass {@code null} to use default bounds.
10721      */
10722     @Override
10723     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10724             Rect initialBounds) {
10725         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10726         synchronized (this) {
10727             long ident = Binder.clearCallingIdentity();
10728             try {
10729                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10730                 if (task == null) {
10731                     Slog.w(TAG, "moveTaskToDockedStack: No task for id=" + taskId);
10732                     return false;
10733                 }
10734
10735                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10736                         + " to createMode=" + createMode + " toTop=" + toTop);
10737                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10738
10739                 // Defer resuming until we move the home stack to the front below
10740                 final boolean moved = task.reparent(DOCKED_STACK_ID, toTop,
10741                         REPARENT_KEEP_STACK_AT_FRONT, animate, !DEFER_RESUME,
10742                         "moveTaskToDockedStack");
10743                 if (moved) {
10744                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10745                 }
10746                 return moved;
10747             } finally {
10748                 Binder.restoreCallingIdentity(ident);
10749             }
10750         }
10751     }
10752
10753     /**
10754      * Moves the top activity in the input stackId to the pinned stack.
10755      *
10756      * @param stackId Id of stack to move the top activity to pinned stack.
10757      * @param bounds Bounds to use for pinned stack.
10758      *
10759      * @return True if the top activity of the input stack was successfully moved to the pinned
10760      *          stack.
10761      */
10762     @Override
10763     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10764         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10765         synchronized (this) {
10766             if (!mSupportsPictureInPicture) {
10767                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10768                         + "Device doesn't support picture-in-picture mode");
10769             }
10770
10771             long ident = Binder.clearCallingIdentity();
10772             try {
10773                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10774             } finally {
10775                 Binder.restoreCallingIdentity(ident);
10776             }
10777         }
10778     }
10779
10780     @Override
10781     public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode,
10782             boolean preserveWindows, boolean animate, int animationDuration) {
10783         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10784         long ident = Binder.clearCallingIdentity();
10785         try {
10786             synchronized (this) {
10787                 if (animate) {
10788                     if (stackId == PINNED_STACK_ID) {
10789                         final PinnedActivityStack pinnedStack =
10790                                 mStackSupervisor.getStack(PINNED_STACK_ID);
10791                         if (pinnedStack != null) {
10792                             pinnedStack.animateResizePinnedStack(null /* sourceHintBounds */,
10793                                     destBounds, animationDuration, false /* fromFullscreen */);
10794                         }
10795                     } else {
10796                         throw new IllegalArgumentException("Stack: " + stackId
10797                                 + " doesn't support animated resize.");
10798                     }
10799                 } else {
10800                     mStackSupervisor.resizeStackLocked(stackId, destBounds, null /* tempTaskBounds */,
10801                             null /* tempTaskInsetBounds */, preserveWindows,
10802                             allowResizeInDockedMode, !DEFER_RESUME);
10803                 }
10804             }
10805         } finally {
10806             Binder.restoreCallingIdentity(ident);
10807         }
10808     }
10809
10810     @Override
10811     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10812             Rect tempDockedTaskInsetBounds,
10813             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10814         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10815                 "resizeDockedStack()");
10816         long ident = Binder.clearCallingIdentity();
10817         try {
10818             synchronized (this) {
10819                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10820                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10821                         PRESERVE_WINDOWS);
10822             }
10823         } finally {
10824             Binder.restoreCallingIdentity(ident);
10825         }
10826     }
10827
10828     @Override
10829     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10830         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10831                 "resizePinnedStack()");
10832         final long ident = Binder.clearCallingIdentity();
10833         try {
10834             synchronized (this) {
10835                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10836             }
10837         } finally {
10838             Binder.restoreCallingIdentity(ident);
10839         }
10840     }
10841
10842     /**
10843      * Try to place task to provided position. The final position might be different depending on
10844      * current user and stacks state. The task will be moved to target stack if it's currently in
10845      * different stack.
10846      */
10847     @Override
10848     public void positionTaskInStack(int taskId, int stackId, int position) {
10849         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10850         if (StackId.isHomeOrRecentsStack(stackId)) {
10851             throw new IllegalArgumentException(
10852                     "positionTaskInStack: Attempt to change the position of task "
10853                     + taskId + " in/to home/recents stack");
10854         }
10855         synchronized (this) {
10856             long ident = Binder.clearCallingIdentity();
10857             try {
10858                 if (DEBUG_STACK) Slog.d(TAG_STACK, "positionTaskInStack: positioning task="
10859                         + taskId + " in stackId=" + stackId + " at position=" + position);
10860                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10861                 if (task == null) {
10862                     throw new IllegalArgumentException("positionTaskInStack: no task for id="
10863                             + taskId);
10864                 }
10865
10866                 final ActivityStack stack = mStackSupervisor.getStack(stackId, CREATE_IF_NEEDED,
10867                         !ON_TOP);
10868
10869                 // TODO: Have the callers of this API call a separate reparent method if that is
10870                 // what they intended to do vs. having this method also do reparenting.
10871                 if (task.getStack() == stack) {
10872                     // Change position in current stack.
10873                     stack.positionChildAt(task, position);
10874                 } else {
10875                     // Reparent to new stack.
10876                     task.reparent(stackId, position, REPARENT_LEAVE_STACK_IN_PLACE,
10877                             !ANIMATE, !DEFER_RESUME, "positionTaskInStack");
10878                 }
10879             } finally {
10880                 Binder.restoreCallingIdentity(ident);
10881             }
10882         }
10883     }
10884
10885     @Override
10886     public List<StackInfo> getAllStackInfos() {
10887         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10888         long ident = Binder.clearCallingIdentity();
10889         try {
10890             synchronized (this) {
10891                 return mStackSupervisor.getAllStackInfosLocked();
10892             }
10893         } finally {
10894             Binder.restoreCallingIdentity(ident);
10895         }
10896     }
10897
10898     @Override
10899     public StackInfo getStackInfo(int stackId) {
10900         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10901         long ident = Binder.clearCallingIdentity();
10902         try {
10903             synchronized (this) {
10904                 return mStackSupervisor.getStackInfoLocked(stackId);
10905             }
10906         } finally {
10907             Binder.restoreCallingIdentity(ident);
10908         }
10909     }
10910
10911     @Override
10912     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10913         synchronized(this) {
10914             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10915         }
10916     }
10917
10918     @Override
10919     public void updateDeviceOwner(String packageName) {
10920         final int callingUid = Binder.getCallingUid();
10921         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10922             throw new SecurityException("updateDeviceOwner called from non-system process");
10923         }
10924         synchronized (this) {
10925             mDeviceOwnerName = packageName;
10926         }
10927     }
10928
10929     @Override
10930     public void updateLockTaskPackages(int userId, String[] packages) {
10931         final int callingUid = Binder.getCallingUid();
10932         if (callingUid != 0 && callingUid != SYSTEM_UID) {
10933             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10934                     "updateLockTaskPackages()");
10935         }
10936         synchronized (this) {
10937             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10938                     Arrays.toString(packages));
10939             mLockTaskPackages.put(userId, packages);
10940             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10941         }
10942     }
10943
10944
10945     void startLockTaskModeLocked(TaskRecord task) {
10946         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10947         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10948             return;
10949         }
10950
10951         // When a task is locked, dismiss the pinned stack if it exists
10952         final PinnedActivityStack pinnedStack = mStackSupervisor.getStack(
10953                 PINNED_STACK_ID);
10954         if (pinnedStack != null) {
10955             mStackSupervisor.removeStackLocked(PINNED_STACK_ID);
10956         }
10957
10958         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10959         // is initiated by system after the pinning request was shown and locked mode is initiated
10960         // by an authorized app directly
10961         final int callingUid = Binder.getCallingUid();
10962         boolean isSystemInitiated = callingUid == SYSTEM_UID;
10963         long ident = Binder.clearCallingIdentity();
10964         try {
10965             if (!isSystemInitiated) {
10966                 task.mLockTaskUid = callingUid;
10967                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10968                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10969                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10970                     StatusBarManagerInternal statusBarManager =
10971                             LocalServices.getService(StatusBarManagerInternal.class);
10972                     if (statusBarManager != null) {
10973                         statusBarManager.showScreenPinningRequest(task.taskId);
10974                     }
10975                     return;
10976                 }
10977
10978                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10979                 if (stack == null || task != stack.topTask()) {
10980                     throw new IllegalArgumentException("Invalid task, not in foreground");
10981                 }
10982             }
10983             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10984                     "Locking fully");
10985             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10986                     ActivityManager.LOCK_TASK_MODE_PINNED :
10987                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10988                     "startLockTask", true);
10989         } finally {
10990             Binder.restoreCallingIdentity(ident);
10991         }
10992     }
10993
10994     @Override
10995     public void startLockTaskModeById(int taskId) {
10996         synchronized (this) {
10997             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10998             if (task != null) {
10999                 startLockTaskModeLocked(task);
11000             }
11001         }
11002     }
11003
11004     @Override
11005     public void startLockTaskModeByToken(IBinder token) {
11006         synchronized (this) {
11007             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11008             if (r == null) {
11009                 return;
11010             }
11011             final TaskRecord task = r.getTask();
11012             if (task != null) {
11013                 startLockTaskModeLocked(task);
11014             }
11015         }
11016     }
11017
11018     @Override
11019     public void startSystemLockTaskMode(int taskId) throws RemoteException {
11020         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
11021         // This makes inner call to look as if it was initiated by system.
11022         long ident = Binder.clearCallingIdentity();
11023         try {
11024             synchronized (this) {
11025                 startLockTaskModeById(taskId);
11026             }
11027         } finally {
11028             Binder.restoreCallingIdentity(ident);
11029         }
11030     }
11031
11032     @Override
11033     public void stopLockTaskMode() {
11034         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
11035         if (lockTask == null) {
11036             // Our work here is done.
11037             return;
11038         }
11039
11040         final int callingUid = Binder.getCallingUid();
11041         final int lockTaskUid = lockTask.mLockTaskUid;
11042         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
11043         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
11044             // Done.
11045             return;
11046         } else {
11047             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
11048             // It is possible lockTaskMode was started by the system process because
11049             // android:lockTaskMode is set to a locking value in the application manifest
11050             // instead of the app calling startLockTaskMode. In this case
11051             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
11052             // {@link TaskRecord.effectiveUid} instead. Also caller with
11053             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
11054             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
11055                     && callingUid != lockTaskUid
11056                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
11057                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
11058                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
11059             }
11060         }
11061         long ident = Binder.clearCallingIdentity();
11062         try {
11063             Log.d(TAG, "stopLockTaskMode");
11064             // Stop lock task
11065             synchronized (this) {
11066                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
11067                         "stopLockTask", true);
11068             }
11069             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
11070             if (tm != null) {
11071                 tm.showInCallScreen(false);
11072             }
11073         } finally {
11074             Binder.restoreCallingIdentity(ident);
11075         }
11076     }
11077
11078     /**
11079      * This API should be called by SystemUI only when user perform certain action to dismiss
11080      * lock task mode. We should only dismiss pinned lock task mode in this case.
11081      */
11082     @Override
11083     public void stopSystemLockTaskMode() throws RemoteException {
11084         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
11085             stopLockTaskMode();
11086         } else {
11087             mStackSupervisor.showLockTaskToast();
11088         }
11089     }
11090
11091     @Override
11092     public boolean isInLockTaskMode() {
11093         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
11094     }
11095
11096     @Override
11097     public int getLockTaskModeState() {
11098         synchronized (this) {
11099             return mStackSupervisor.getLockTaskModeState();
11100         }
11101     }
11102
11103     @Override
11104     public void showLockTaskEscapeMessage(IBinder token) {
11105         synchronized (this) {
11106             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
11107             if (r == null) {
11108                 return;
11109             }
11110             mStackSupervisor.showLockTaskEscapeMessageLocked(r.getTask());
11111         }
11112     }
11113
11114     @Override
11115     public void setDisablePreviewScreenshots(IBinder token, boolean disable)
11116             throws RemoteException {
11117         synchronized (this) {
11118             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11119             if (r == null) {
11120                 Slog.w(TAG, "setDisablePreviewScreenshots: Unable to find activity for token="
11121                         + token);
11122                 return;
11123             }
11124             final long origId = Binder.clearCallingIdentity();
11125             try {
11126                 r.setDisablePreviewScreenshots(disable);
11127             } finally {
11128                 Binder.restoreCallingIdentity(origId);
11129             }
11130         }
11131     }
11132
11133     // =========================================================
11134     // CONTENT PROVIDERS
11135     // =========================================================
11136
11137     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
11138         List<ProviderInfo> providers = null;
11139         try {
11140             providers = AppGlobals.getPackageManager()
11141                     .queryContentProviders(app.processName, app.uid,
11142                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11143                                     | MATCH_DEBUG_TRIAGED_MISSING, /*metadastaKey=*/ null)
11144                     .getList();
11145         } catch (RemoteException ex) {
11146         }
11147         if (DEBUG_MU) Slog.v(TAG_MU,
11148                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
11149         int userId = app.userId;
11150         if (providers != null) {
11151             int N = providers.size();
11152             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
11153             for (int i=0; i<N; i++) {
11154                 // TODO: keep logic in sync with installEncryptionUnawareProviders
11155                 ProviderInfo cpi =
11156                     (ProviderInfo)providers.get(i);
11157                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11158                         cpi.name, cpi.flags);
11159                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
11160                     // This is a singleton provider, but a user besides the
11161                     // default user is asking to initialize a process it runs
11162                     // in...  well, no, it doesn't actually run in this process,
11163                     // it runs in the process of the default user.  Get rid of it.
11164                     providers.remove(i);
11165                     N--;
11166                     i--;
11167                     continue;
11168                 }
11169
11170                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11171                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
11172                 if (cpr == null) {
11173                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
11174                     mProviderMap.putProviderByClass(comp, cpr);
11175                 }
11176                 if (DEBUG_MU) Slog.v(TAG_MU,
11177                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
11178                 app.pubProviders.put(cpi.name, cpr);
11179                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
11180                     // Don't add this if it is a platform component that is marked
11181                     // to run in multiple processes, because this is actually
11182                     // part of the framework so doesn't make sense to track as a
11183                     // separate apk in the process.
11184                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
11185                             mProcessStats);
11186                 }
11187                 notifyPackageUse(cpi.applicationInfo.packageName,
11188                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
11189             }
11190         }
11191         return providers;
11192     }
11193
11194     /**
11195      * Check if the calling UID has a possible chance at accessing the provider
11196      * at the given authority and user.
11197      */
11198     public String checkContentProviderAccess(String authority, int userId) {
11199         if (userId == UserHandle.USER_ALL) {
11200             mContext.enforceCallingOrSelfPermission(
11201                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
11202             userId = UserHandle.getCallingUserId();
11203         }
11204
11205         ProviderInfo cpi = null;
11206         try {
11207             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
11208                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
11209                             | PackageManager.MATCH_DISABLED_COMPONENTS
11210                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
11211                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
11212                     userId);
11213         } catch (RemoteException ignored) {
11214         }
11215         if (cpi == null) {
11216             return "Failed to find provider " + authority + " for user " + userId
11217                     + "; expected to find a valid ContentProvider for this authority";
11218         }
11219
11220         ProcessRecord r = null;
11221         synchronized (mPidsSelfLocked) {
11222             r = mPidsSelfLocked.get(Binder.getCallingPid());
11223         }
11224         if (r == null) {
11225             return "Failed to find PID " + Binder.getCallingPid();
11226         }
11227
11228         synchronized (this) {
11229             return checkContentProviderPermissionLocked(cpi, r, userId, true);
11230         }
11231     }
11232
11233     /**
11234      * Check if {@link ProcessRecord} has a possible chance at accessing the
11235      * given {@link ProviderInfo}. Final permission checking is always done
11236      * in {@link ContentProvider}.
11237      */
11238     private final String checkContentProviderPermissionLocked(
11239             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
11240         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
11241         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
11242         boolean checkedGrants = false;
11243         if (checkUser) {
11244             // Looking for cross-user grants before enforcing the typical cross-users permissions
11245             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
11246             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
11247                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
11248                     return null;
11249                 }
11250                 checkedGrants = true;
11251             }
11252             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
11253                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
11254             if (userId != tmpTargetUserId) {
11255                 // When we actually went to determine the final targer user ID, this ended
11256                 // up different than our initial check for the authority.  This is because
11257                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
11258                 // SELF.  So we need to re-check the grants again.
11259                 checkedGrants = false;
11260             }
11261         }
11262         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
11263                 cpi.applicationInfo.uid, cpi.exported)
11264                 == PackageManager.PERMISSION_GRANTED) {
11265             return null;
11266         }
11267         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
11268                 cpi.applicationInfo.uid, cpi.exported)
11269                 == PackageManager.PERMISSION_GRANTED) {
11270             return null;
11271         }
11272
11273         PathPermission[] pps = cpi.pathPermissions;
11274         if (pps != null) {
11275             int i = pps.length;
11276             while (i > 0) {
11277                 i--;
11278                 PathPermission pp = pps[i];
11279                 String pprperm = pp.getReadPermission();
11280                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
11281                         cpi.applicationInfo.uid, cpi.exported)
11282                         == PackageManager.PERMISSION_GRANTED) {
11283                     return null;
11284                 }
11285                 String ppwperm = pp.getWritePermission();
11286                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
11287                         cpi.applicationInfo.uid, cpi.exported)
11288                         == PackageManager.PERMISSION_GRANTED) {
11289                     return null;
11290                 }
11291             }
11292         }
11293         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
11294             return null;
11295         }
11296
11297         final String suffix;
11298         if (!cpi.exported) {
11299             suffix = " that is not exported from UID " + cpi.applicationInfo.uid;
11300         } else if (android.Manifest.permission.MANAGE_DOCUMENTS.equals(cpi.readPermission)) {
11301             suffix = " requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs";
11302         } else {
11303             suffix = " requires " + cpi.readPermission + " or " + cpi.writePermission;
11304         }
11305         final String msg = "Permission Denial: opening provider " + cpi.name
11306                 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
11307                 + ", uid=" + callingUid + ")" + suffix;
11308         Slog.w(TAG, msg);
11309         return msg;
11310     }
11311
11312     /**
11313      * Returns if the ContentProvider has granted a uri to callingUid
11314      */
11315     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
11316         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
11317         if (perms != null) {
11318             for (int i=perms.size()-1; i>=0; i--) {
11319                 GrantUri grantUri = perms.keyAt(i);
11320                 if (grantUri.sourceUserId == userId || !checkUser) {
11321                     if (matchesProvider(grantUri.uri, cpi)) {
11322                         return true;
11323                     }
11324                 }
11325             }
11326         }
11327         return false;
11328     }
11329
11330     /**
11331      * Returns true if the uri authority is one of the authorities specified in the provider.
11332      */
11333     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
11334         String uriAuth = uri.getAuthority();
11335         String cpiAuth = cpi.authority;
11336         if (cpiAuth.indexOf(';') == -1) {
11337             return cpiAuth.equals(uriAuth);
11338         }
11339         String[] cpiAuths = cpiAuth.split(";");
11340         int length = cpiAuths.length;
11341         for (int i = 0; i < length; i++) {
11342             if (cpiAuths[i].equals(uriAuth)) return true;
11343         }
11344         return false;
11345     }
11346
11347     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
11348             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11349         if (r != null) {
11350             for (int i=0; i<r.conProviders.size(); i++) {
11351                 ContentProviderConnection conn = r.conProviders.get(i);
11352                 if (conn.provider == cpr) {
11353                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11354                             "Adding provider requested by "
11355                             + r.processName + " from process "
11356                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11357                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11358                     if (stable) {
11359                         conn.stableCount++;
11360                         conn.numStableIncs++;
11361                     } else {
11362                         conn.unstableCount++;
11363                         conn.numUnstableIncs++;
11364                     }
11365                     return conn;
11366                 }
11367             }
11368             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
11369             if (stable) {
11370                 conn.stableCount = 1;
11371                 conn.numStableIncs = 1;
11372             } else {
11373                 conn.unstableCount = 1;
11374                 conn.numUnstableIncs = 1;
11375             }
11376             cpr.connections.add(conn);
11377             r.conProviders.add(conn);
11378             startAssociationLocked(r.uid, r.processName, r.curProcState,
11379                     cpr.uid, cpr.name, cpr.info.processName);
11380             return conn;
11381         }
11382         cpr.addExternalProcessHandleLocked(externalProcessToken);
11383         return null;
11384     }
11385
11386     boolean decProviderCountLocked(ContentProviderConnection conn,
11387             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
11388         if (conn != null) {
11389             cpr = conn.provider;
11390             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
11391                     "Removing provider requested by "
11392                     + conn.client.processName + " from process "
11393                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
11394                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
11395             if (stable) {
11396                 conn.stableCount--;
11397             } else {
11398                 conn.unstableCount--;
11399             }
11400             if (conn.stableCount == 0 && conn.unstableCount == 0) {
11401                 cpr.connections.remove(conn);
11402                 conn.client.conProviders.remove(conn);
11403                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
11404                     // The client is more important than last activity -- note the time this
11405                     // is happening, so we keep the old provider process around a bit as last
11406                     // activity to avoid thrashing it.
11407                     if (cpr.proc != null) {
11408                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
11409                     }
11410                 }
11411                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
11412                 return true;
11413             }
11414             return false;
11415         }
11416         cpr.removeExternalProcessHandleLocked(externalProcessToken);
11417         return false;
11418     }
11419
11420     private void checkTime(long startTime, String where) {
11421         long now = SystemClock.uptimeMillis();
11422         if ((now-startTime) > 50) {
11423             // If we are taking more than 50ms, log about it.
11424             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
11425         }
11426     }
11427
11428     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
11429             PROC_SPACE_TERM,
11430             PROC_SPACE_TERM|PROC_PARENS,
11431             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
11432     };
11433
11434     private final long[] mProcessStateStatsLongs = new long[1];
11435
11436     boolean isProcessAliveLocked(ProcessRecord proc) {
11437         if (proc.procStatFile == null) {
11438             proc.procStatFile = "/proc/" + proc.pid + "/stat";
11439         }
11440         mProcessStateStatsLongs[0] = 0;
11441         if (!readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
11442                 mProcessStateStatsLongs, null)) {
11443             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
11444             return false;
11445         }
11446         final long state = mProcessStateStatsLongs[0];
11447         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
11448                 + (char)state);
11449         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
11450     }
11451
11452     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11453             String name, IBinder token, boolean stable, int userId) {
11454         ContentProviderRecord cpr;
11455         ContentProviderConnection conn = null;
11456         ProviderInfo cpi = null;
11457
11458         synchronized(this) {
11459             long startTime = SystemClock.uptimeMillis();
11460
11461             ProcessRecord r = null;
11462             if (caller != null) {
11463                 r = getRecordForAppLocked(caller);
11464                 if (r == null) {
11465                     throw new SecurityException(
11466                             "Unable to find app for caller " + caller
11467                           + " (pid=" + Binder.getCallingPid()
11468                           + ") when getting content provider " + name);
11469                 }
11470             }
11471
11472             boolean checkCrossUser = true;
11473
11474             checkTime(startTime, "getContentProviderImpl: getProviderByName");
11475
11476             // First check if this content provider has been published...
11477             cpr = mProviderMap.getProviderByName(name, userId);
11478             // If that didn't work, check if it exists for user 0 and then
11479             // verify that it's a singleton provider before using it.
11480             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
11481                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
11482                 if (cpr != null) {
11483                     cpi = cpr.info;
11484                     if (isSingleton(cpi.processName, cpi.applicationInfo,
11485                             cpi.name, cpi.flags)
11486                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
11487                         userId = UserHandle.USER_SYSTEM;
11488                         checkCrossUser = false;
11489                     } else {
11490                         cpr = null;
11491                         cpi = null;
11492                     }
11493                 }
11494             }
11495
11496             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
11497             if (providerRunning) {
11498                 cpi = cpr.info;
11499                 String msg;
11500                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11501                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
11502                         != null) {
11503                     throw new SecurityException(msg);
11504                 }
11505                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11506
11507                 if (r != null && cpr.canRunHere(r)) {
11508                     // This provider has been published or is in the process
11509                     // of being published...  but it is also allowed to run
11510                     // in the caller's process, so don't make a connection
11511                     // and just let the caller instantiate its own instance.
11512                     ContentProviderHolder holder = cpr.newHolder(null);
11513                     // don't give caller the provider object, it needs
11514                     // to make its own.
11515                     holder.provider = null;
11516                     return holder;
11517                 }
11518                 // Don't expose providers between normal apps and instant apps
11519                 try {
11520                     if (AppGlobals.getPackageManager()
11521                             .resolveContentProvider(name, 0 /*flags*/, userId) == null) {
11522                         return null;
11523                     }
11524                 } catch (RemoteException e) {
11525                 }
11526
11527                 final long origId = Binder.clearCallingIdentity();
11528
11529                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
11530
11531                 // In this case the provider instance already exists, so we can
11532                 // return it right away.
11533                 conn = incProviderCountLocked(r, cpr, token, stable);
11534                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
11535                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
11536                         // If this is a perceptible app accessing the provider,
11537                         // make sure to count it as being accessed and thus
11538                         // back up on the LRU list.  This is good because
11539                         // content providers are often expensive to start.
11540                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
11541                         updateLruProcessLocked(cpr.proc, false, null);
11542                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
11543                     }
11544                 }
11545
11546                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
11547                 final int verifiedAdj = cpr.proc.verifiedAdj;
11548                 boolean success = updateOomAdjLocked(cpr.proc, true);
11549                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
11550                 // if the process has been successfully adjusted.  So to reduce races with
11551                 // it, we will check whether the process still exists.  Note that this doesn't
11552                 // completely get rid of races with LMK killing the process, but should make
11553                 // them much smaller.
11554                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
11555                     success = false;
11556                 }
11557                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
11558                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
11559                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
11560                 // NOTE: there is still a race here where a signal could be
11561                 // pending on the process even though we managed to update its
11562                 // adj level.  Not sure what to do about this, but at least
11563                 // the race is now smaller.
11564                 if (!success) {
11565                     // Uh oh...  it looks like the provider's process
11566                     // has been killed on us.  We need to wait for a new
11567                     // process to be started, and make sure its death
11568                     // doesn't kill our process.
11569                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
11570                             + " is crashing; detaching " + r);
11571                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
11572                     checkTime(startTime, "getContentProviderImpl: before appDied");
11573                     appDiedLocked(cpr.proc);
11574                     checkTime(startTime, "getContentProviderImpl: after appDied");
11575                     if (!lastRef) {
11576                         // This wasn't the last ref our process had on
11577                         // the provider...  we have now been killed, bail.
11578                         return null;
11579                     }
11580                     providerRunning = false;
11581                     conn = null;
11582                 } else {
11583                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
11584                 }
11585
11586                 Binder.restoreCallingIdentity(origId);
11587             }
11588
11589             if (!providerRunning) {
11590                 try {
11591                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
11592                     cpi = AppGlobals.getPackageManager().
11593                         resolveContentProvider(name,
11594                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
11595                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
11596                 } catch (RemoteException ex) {
11597                 }
11598                 if (cpi == null) {
11599                     return null;
11600                 }
11601                 // If the provider is a singleton AND
11602                 // (it's a call within the same user || the provider is a
11603                 // privileged app)
11604                 // Then allow connecting to the singleton provider
11605                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
11606                         cpi.name, cpi.flags)
11607                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
11608                 if (singleton) {
11609                     userId = UserHandle.USER_SYSTEM;
11610                 }
11611                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
11612                 checkTime(startTime, "getContentProviderImpl: got app info for user");
11613
11614                 String msg;
11615                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
11616                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
11617                         != null) {
11618                     throw new SecurityException(msg);
11619                 }
11620                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
11621
11622                 if (!mProcessesReady
11623                         && !cpi.processName.equals("system")) {
11624                     // If this content provider does not run in the system
11625                     // process, and the system is not yet ready to run other
11626                     // processes, then fail fast instead of hanging.
11627                     throw new IllegalArgumentException(
11628                             "Attempt to launch content provider before system ready");
11629                 }
11630
11631                 // Make sure that the user who owns this provider is running.  If not,
11632                 // we don't want to allow it to run.
11633                 if (!mUserController.isUserRunningLocked(userId, 0)) {
11634                     Slog.w(TAG, "Unable to launch app "
11635                             + cpi.applicationInfo.packageName + "/"
11636                             + cpi.applicationInfo.uid + " for provider "
11637                             + name + ": user " + userId + " is stopped");
11638                     return null;
11639                 }
11640
11641                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
11642                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
11643                 cpr = mProviderMap.getProviderByClass(comp, userId);
11644                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
11645                 final boolean firstClass = cpr == null;
11646                 if (firstClass) {
11647                     final long ident = Binder.clearCallingIdentity();
11648
11649                     // If permissions need a review before any of the app components can run,
11650                     // we return no provider and launch a review activity if the calling app
11651                     // is in the foreground.
11652                     if (mPermissionReviewRequired) {
11653                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
11654                             return null;
11655                         }
11656                     }
11657
11658                     try {
11659                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
11660                         ApplicationInfo ai =
11661                             AppGlobals.getPackageManager().
11662                                 getApplicationInfo(
11663                                         cpi.applicationInfo.packageName,
11664                                         STOCK_PM_FLAGS, userId);
11665                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
11666                         if (ai == null) {
11667                             Slog.w(TAG, "No package info for content provider "
11668                                     + cpi.name);
11669                             return null;
11670                         }
11671                         ai = getAppInfoForUser(ai, userId);
11672                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
11673                     } catch (RemoteException ex) {
11674                         // pm is in same process, this will never happen.
11675                     } finally {
11676                         Binder.restoreCallingIdentity(ident);
11677                     }
11678                 }
11679
11680                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
11681
11682                 if (r != null && cpr.canRunHere(r)) {
11683                     // If this is a multiprocess provider, then just return its
11684                     // info and allow the caller to instantiate it.  Only do
11685                     // this if the provider is the same user as the caller's
11686                     // process, or can run as root (so can be in any process).
11687                     return cpr.newHolder(null);
11688                 }
11689
11690                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
11691                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
11692                             + cpr.info.name + " callers=" + Debug.getCallers(6));
11693
11694                 // This is single process, and our app is now connecting to it.
11695                 // See if we are already in the process of launching this
11696                 // provider.
11697                 final int N = mLaunchingProviders.size();
11698                 int i;
11699                 for (i = 0; i < N; i++) {
11700                     if (mLaunchingProviders.get(i) == cpr) {
11701                         break;
11702                     }
11703                 }
11704
11705                 // If the provider is not already being launched, then get it
11706                 // started.
11707                 if (i >= N) {
11708                     final long origId = Binder.clearCallingIdentity();
11709
11710                     try {
11711                         // Content provider is now in use, its package can't be stopped.
11712                         try {
11713                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
11714                             AppGlobals.getPackageManager().setPackageStoppedState(
11715                                     cpr.appInfo.packageName, false, userId);
11716                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
11717                         } catch (RemoteException e) {
11718                         } catch (IllegalArgumentException e) {
11719                             Slog.w(TAG, "Failed trying to unstop package "
11720                                     + cpr.appInfo.packageName + ": " + e);
11721                         }
11722
11723                         // Use existing process if already started
11724                         checkTime(startTime, "getContentProviderImpl: looking for process record");
11725                         ProcessRecord proc = getProcessRecordLocked(
11726                                 cpi.processName, cpr.appInfo.uid, false);
11727                         if (proc != null && proc.thread != null && !proc.killed) {
11728                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
11729                                     "Installing in existing process " + proc);
11730                             if (!proc.pubProviders.containsKey(cpi.name)) {
11731                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
11732                                 proc.pubProviders.put(cpi.name, cpr);
11733                                 try {
11734                                     proc.thread.scheduleInstallProvider(cpi);
11735                                 } catch (RemoteException e) {
11736                                 }
11737                             }
11738                         } else {
11739                             checkTime(startTime, "getContentProviderImpl: before start process");
11740                             proc = startProcessLocked(cpi.processName,
11741                                     cpr.appInfo, false, 0, "content provider",
11742                                     new ComponentName(cpi.applicationInfo.packageName,
11743                                             cpi.name), false, false, false);
11744                             checkTime(startTime, "getContentProviderImpl: after start process");
11745                             if (proc == null) {
11746                                 Slog.w(TAG, "Unable to launch app "
11747                                         + cpi.applicationInfo.packageName + "/"
11748                                         + cpi.applicationInfo.uid + " for provider "
11749                                         + name + ": process is bad");
11750                                 return null;
11751                             }
11752                         }
11753                         cpr.launchingApp = proc;
11754                         mLaunchingProviders.add(cpr);
11755                     } finally {
11756                         Binder.restoreCallingIdentity(origId);
11757                     }
11758                 }
11759
11760                 checkTime(startTime, "getContentProviderImpl: updating data structures");
11761
11762                 // Make sure the provider is published (the same provider class
11763                 // may be published under multiple names).
11764                 if (firstClass) {
11765                     mProviderMap.putProviderByClass(comp, cpr);
11766                 }
11767
11768                 mProviderMap.putProviderByName(name, cpr);
11769                 conn = incProviderCountLocked(r, cpr, token, stable);
11770                 if (conn != null) {
11771                     conn.waiting = true;
11772                 }
11773             }
11774             checkTime(startTime, "getContentProviderImpl: done!");
11775
11776             grantEphemeralAccessLocked(userId, null /*intent*/,
11777                     cpi.applicationInfo.uid, UserHandle.getAppId(Binder.getCallingUid()));
11778         }
11779
11780         // Wait for the provider to be published...
11781         synchronized (cpr) {
11782             while (cpr.provider == null) {
11783                 if (cpr.launchingApp == null) {
11784                     Slog.w(TAG, "Unable to launch app "
11785                             + cpi.applicationInfo.packageName + "/"
11786                             + cpi.applicationInfo.uid + " for provider "
11787                             + name + ": launching app became null");
11788                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11789                             UserHandle.getUserId(cpi.applicationInfo.uid),
11790                             cpi.applicationInfo.packageName,
11791                             cpi.applicationInfo.uid, name);
11792                     return null;
11793                 }
11794                 try {
11795                     if (DEBUG_MU) Slog.v(TAG_MU,
11796                             "Waiting to start provider " + cpr
11797                             + " launchingApp=" + cpr.launchingApp);
11798                     if (conn != null) {
11799                         conn.waiting = true;
11800                     }
11801                     cpr.wait();
11802                 } catch (InterruptedException ex) {
11803                 } finally {
11804                     if (conn != null) {
11805                         conn.waiting = false;
11806                     }
11807                 }
11808             }
11809         }
11810         return cpr != null ? cpr.newHolder(conn) : null;
11811     }
11812
11813     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11814             ProcessRecord r, final int userId) {
11815         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11816                 cpi.packageName, userId)) {
11817
11818             final boolean callerForeground = r == null || r.setSchedGroup
11819                     != ProcessList.SCHED_GROUP_BACKGROUND;
11820
11821             // Show a permission review UI only for starting from a foreground app
11822             if (!callerForeground) {
11823                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11824                         + cpi.packageName + " requires a permissions review");
11825                 return false;
11826             }
11827
11828             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11829             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11830                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11831             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11832
11833             if (DEBUG_PERMISSIONS_REVIEW) {
11834                 Slog.i(TAG, "u" + userId + " Launching permission review "
11835                         + "for package " + cpi.packageName);
11836             }
11837
11838             final UserHandle userHandle = new UserHandle(userId);
11839             mHandler.post(new Runnable() {
11840                 @Override
11841                 public void run() {
11842                     mContext.startActivityAsUser(intent, userHandle);
11843                 }
11844             });
11845
11846             return false;
11847         }
11848
11849         return true;
11850     }
11851
11852     PackageManagerInternal getPackageManagerInternalLocked() {
11853         if (mPackageManagerInt == null) {
11854             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11855         }
11856         return mPackageManagerInt;
11857     }
11858
11859     @Override
11860     public final ContentProviderHolder getContentProvider(
11861             IApplicationThread caller, String name, int userId, boolean stable) {
11862         enforceNotIsolatedCaller("getContentProvider");
11863         if (caller == null) {
11864             String msg = "null IApplicationThread when getting content provider "
11865                     + name;
11866             Slog.w(TAG, msg);
11867             throw new SecurityException(msg);
11868         }
11869         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11870         // with cross-user grant.
11871         return getContentProviderImpl(caller, name, null, stable, userId);
11872     }
11873
11874     public ContentProviderHolder getContentProviderExternal(
11875             String name, int userId, IBinder token) {
11876         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11877             "Do not have permission in call getContentProviderExternal()");
11878         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11879                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11880         return getContentProviderExternalUnchecked(name, token, userId);
11881     }
11882
11883     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11884             IBinder token, int userId) {
11885         return getContentProviderImpl(null, name, token, true, userId);
11886     }
11887
11888     /**
11889      * Drop a content provider from a ProcessRecord's bookkeeping
11890      */
11891     public void removeContentProvider(IBinder connection, boolean stable) {
11892         enforceNotIsolatedCaller("removeContentProvider");
11893         long ident = Binder.clearCallingIdentity();
11894         try {
11895             synchronized (this) {
11896                 ContentProviderConnection conn;
11897                 try {
11898                     conn = (ContentProviderConnection)connection;
11899                 } catch (ClassCastException e) {
11900                     String msg ="removeContentProvider: " + connection
11901                             + " not a ContentProviderConnection";
11902                     Slog.w(TAG, msg);
11903                     throw new IllegalArgumentException(msg);
11904                 }
11905                 if (conn == null) {
11906                     throw new NullPointerException("connection is null");
11907                 }
11908                 if (decProviderCountLocked(conn, null, null, stable)) {
11909                     updateOomAdjLocked();
11910                 }
11911             }
11912         } finally {
11913             Binder.restoreCallingIdentity(ident);
11914         }
11915     }
11916
11917     public void removeContentProviderExternal(String name, IBinder token) {
11918         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11919             "Do not have permission in call removeContentProviderExternal()");
11920         int userId = UserHandle.getCallingUserId();
11921         long ident = Binder.clearCallingIdentity();
11922         try {
11923             removeContentProviderExternalUnchecked(name, token, userId);
11924         } finally {
11925             Binder.restoreCallingIdentity(ident);
11926         }
11927     }
11928
11929     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11930         synchronized (this) {
11931             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11932             if(cpr == null) {
11933                 //remove from mProvidersByClass
11934                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11935                 return;
11936             }
11937
11938             //update content provider record entry info
11939             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11940             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11941             if (localCpr.hasExternalProcessHandles()) {
11942                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11943                     updateOomAdjLocked();
11944                 } else {
11945                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11946                             + " with no external reference for token: "
11947                             + token + ".");
11948                 }
11949             } else {
11950                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11951                         + " with no external references.");
11952             }
11953         }
11954     }
11955
11956     public final void publishContentProviders(IApplicationThread caller,
11957             List<ContentProviderHolder> providers) {
11958         if (providers == null) {
11959             return;
11960         }
11961
11962         enforceNotIsolatedCaller("publishContentProviders");
11963         synchronized (this) {
11964             final ProcessRecord r = getRecordForAppLocked(caller);
11965             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11966             if (r == null) {
11967                 throw new SecurityException(
11968                         "Unable to find app for caller " + caller
11969                       + " (pid=" + Binder.getCallingPid()
11970                       + ") when publishing content providers");
11971             }
11972
11973             final long origId = Binder.clearCallingIdentity();
11974
11975             final int N = providers.size();
11976             for (int i = 0; i < N; i++) {
11977                 ContentProviderHolder src = providers.get(i);
11978                 if (src == null || src.info == null || src.provider == null) {
11979                     continue;
11980                 }
11981                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11982                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11983                 if (dst != null) {
11984                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11985                     mProviderMap.putProviderByClass(comp, dst);
11986                     String names[] = dst.info.authority.split(";");
11987                     for (int j = 0; j < names.length; j++) {
11988                         mProviderMap.putProviderByName(names[j], dst);
11989                     }
11990
11991                     int launchingCount = mLaunchingProviders.size();
11992                     int j;
11993                     boolean wasInLaunchingProviders = false;
11994                     for (j = 0; j < launchingCount; j++) {
11995                         if (mLaunchingProviders.get(j) == dst) {
11996                             mLaunchingProviders.remove(j);
11997                             wasInLaunchingProviders = true;
11998                             j--;
11999                             launchingCount--;
12000                         }
12001                     }
12002                     if (wasInLaunchingProviders) {
12003                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
12004                     }
12005                     synchronized (dst) {
12006                         dst.provider = src.provider;
12007                         dst.proc = r;
12008                         dst.notifyAll();
12009                     }
12010                     updateOomAdjLocked(r, true);
12011                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
12012                             src.info.authority);
12013                 }
12014             }
12015
12016             Binder.restoreCallingIdentity(origId);
12017         }
12018     }
12019
12020     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
12021         ContentProviderConnection conn;
12022         try {
12023             conn = (ContentProviderConnection)connection;
12024         } catch (ClassCastException e) {
12025             String msg ="refContentProvider: " + connection
12026                     + " not a ContentProviderConnection";
12027             Slog.w(TAG, msg);
12028             throw new IllegalArgumentException(msg);
12029         }
12030         if (conn == null) {
12031             throw new NullPointerException("connection is null");
12032         }
12033
12034         synchronized (this) {
12035             if (stable > 0) {
12036                 conn.numStableIncs += stable;
12037             }
12038             stable = conn.stableCount + stable;
12039             if (stable < 0) {
12040                 throw new IllegalStateException("stableCount < 0: " + stable);
12041             }
12042
12043             if (unstable > 0) {
12044                 conn.numUnstableIncs += unstable;
12045             }
12046             unstable = conn.unstableCount + unstable;
12047             if (unstable < 0) {
12048                 throw new IllegalStateException("unstableCount < 0: " + unstable);
12049             }
12050
12051             if ((stable+unstable) <= 0) {
12052                 throw new IllegalStateException("ref counts can't go to zero here: stable="
12053                         + stable + " unstable=" + unstable);
12054             }
12055             conn.stableCount = stable;
12056             conn.unstableCount = unstable;
12057             return !conn.dead;
12058         }
12059     }
12060
12061     public void unstableProviderDied(IBinder connection) {
12062         ContentProviderConnection conn;
12063         try {
12064             conn = (ContentProviderConnection)connection;
12065         } catch (ClassCastException e) {
12066             String msg ="refContentProvider: " + connection
12067                     + " not a ContentProviderConnection";
12068             Slog.w(TAG, msg);
12069             throw new IllegalArgumentException(msg);
12070         }
12071         if (conn == null) {
12072             throw new NullPointerException("connection is null");
12073         }
12074
12075         // Safely retrieve the content provider associated with the connection.
12076         IContentProvider provider;
12077         synchronized (this) {
12078             provider = conn.provider.provider;
12079         }
12080
12081         if (provider == null) {
12082             // Um, yeah, we're way ahead of you.
12083             return;
12084         }
12085
12086         // Make sure the caller is being honest with us.
12087         if (provider.asBinder().pingBinder()) {
12088             // Er, no, still looks good to us.
12089             synchronized (this) {
12090                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
12091                         + " says " + conn + " died, but we don't agree");
12092                 return;
12093             }
12094         }
12095
12096         // Well look at that!  It's dead!
12097         synchronized (this) {
12098             if (conn.provider.provider != provider) {
12099                 // But something changed...  good enough.
12100                 return;
12101             }
12102
12103             ProcessRecord proc = conn.provider.proc;
12104             if (proc == null || proc.thread == null) {
12105                 // Seems like the process is already cleaned up.
12106                 return;
12107             }
12108
12109             // As far as we're concerned, this is just like receiving a
12110             // death notification...  just a bit prematurely.
12111             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
12112                     + ") early provider death");
12113             final long ident = Binder.clearCallingIdentity();
12114             try {
12115                 appDiedLocked(proc);
12116             } finally {
12117                 Binder.restoreCallingIdentity(ident);
12118             }
12119         }
12120     }
12121
12122     @Override
12123     public void appNotRespondingViaProvider(IBinder connection) {
12124         enforceCallingPermission(
12125                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
12126
12127         final ContentProviderConnection conn = (ContentProviderConnection) connection;
12128         if (conn == null) {
12129             Slog.w(TAG, "ContentProviderConnection is null");
12130             return;
12131         }
12132
12133         final ProcessRecord host = conn.provider.proc;
12134         if (host == null) {
12135             Slog.w(TAG, "Failed to find hosting ProcessRecord");
12136             return;
12137         }
12138
12139         mHandler.post(new Runnable() {
12140             @Override
12141             public void run() {
12142                 mAppErrors.appNotResponding(host, null, null, false,
12143                         "ContentProvider not responding");
12144             }
12145         });
12146     }
12147
12148     public final void installSystemProviders() {
12149         List<ProviderInfo> providers;
12150         synchronized (this) {
12151             ProcessRecord app = mProcessNames.get("system", SYSTEM_UID);
12152             providers = generateApplicationProvidersLocked(app);
12153             if (providers != null) {
12154                 for (int i=providers.size()-1; i>=0; i--) {
12155                     ProviderInfo pi = (ProviderInfo)providers.get(i);
12156                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
12157                         Slog.w(TAG, "Not installing system proc provider " + pi.name
12158                                 + ": not system .apk");
12159                         providers.remove(i);
12160                     }
12161                 }
12162             }
12163         }
12164         if (providers != null) {
12165             mSystemThread.installSystemProviders(providers);
12166         }
12167
12168         mConstants.start(mContext.getContentResolver());
12169         mCoreSettingsObserver = new CoreSettingsObserver(this);
12170         mFontScaleSettingObserver = new FontScaleSettingObserver();
12171
12172         // Now that the settings provider is published we can consider sending
12173         // in a rescue party.
12174         RescueParty.onSettingsProviderPublished(mContext);
12175
12176         //mUsageStatsService.monitorPackages();
12177     }
12178
12179     private void startPersistentApps(int matchFlags) {
12180         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
12181
12182         synchronized (this) {
12183             try {
12184                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
12185                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
12186                 for (ApplicationInfo app : apps) {
12187                     if (!"android".equals(app.packageName)) {
12188                         addAppLocked(app, null, false, null /* ABI override */);
12189                     }
12190                 }
12191             } catch (RemoteException ex) {
12192             }
12193         }
12194     }
12195
12196     /**
12197      * When a user is unlocked, we need to install encryption-unaware providers
12198      * belonging to any running apps.
12199      */
12200     private void installEncryptionUnawareProviders(int userId) {
12201         // We're only interested in providers that are encryption unaware, and
12202         // we don't care about uninstalled apps, since there's no way they're
12203         // running at this point.
12204         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
12205
12206         synchronized (this) {
12207             final int NP = mProcessNames.getMap().size();
12208             for (int ip = 0; ip < NP; ip++) {
12209                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12210                 final int NA = apps.size();
12211                 for (int ia = 0; ia < NA; ia++) {
12212                     final ProcessRecord app = apps.valueAt(ia);
12213                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
12214
12215                     final int NG = app.pkgList.size();
12216                     for (int ig = 0; ig < NG; ig++) {
12217                         try {
12218                             final String pkgName = app.pkgList.keyAt(ig);
12219                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
12220                                     .getPackageInfo(pkgName, matchFlags, userId);
12221                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
12222                                 for (ProviderInfo pi : pkgInfo.providers) {
12223                                     // TODO: keep in sync with generateApplicationProvidersLocked
12224                                     final boolean processMatch = Objects.equals(pi.processName,
12225                                             app.processName) || pi.multiprocess;
12226                                     final boolean userMatch = isSingleton(pi.processName,
12227                                             pi.applicationInfo, pi.name, pi.flags)
12228                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
12229                                     if (processMatch && userMatch) {
12230                                         Log.v(TAG, "Installing " + pi);
12231                                         app.thread.scheduleInstallProvider(pi);
12232                                     } else {
12233                                         Log.v(TAG, "Skipping " + pi);
12234                                     }
12235                                 }
12236                             }
12237                         } catch (RemoteException ignored) {
12238                         }
12239                     }
12240                 }
12241             }
12242         }
12243     }
12244
12245     /**
12246      * Allows apps to retrieve the MIME type of a URI.
12247      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
12248      * users, then it does not need permission to access the ContentProvider.
12249      * Either, it needs cross-user uri grants.
12250      *
12251      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
12252      *
12253      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
12254      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
12255      */
12256     public String getProviderMimeType(Uri uri, int userId) {
12257         enforceNotIsolatedCaller("getProviderMimeType");
12258         final String name = uri.getAuthority();
12259         int callingUid = Binder.getCallingUid();
12260         int callingPid = Binder.getCallingPid();
12261         long ident = 0;
12262         boolean clearedIdentity = false;
12263         synchronized (this) {
12264             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
12265         }
12266         if (canClearIdentity(callingPid, callingUid, userId)) {
12267             clearedIdentity = true;
12268             ident = Binder.clearCallingIdentity();
12269         }
12270         ContentProviderHolder holder = null;
12271         try {
12272             holder = getContentProviderExternalUnchecked(name, null, userId);
12273             if (holder != null) {
12274                 return holder.provider.getType(uri);
12275             }
12276         } catch (RemoteException e) {
12277             Log.w(TAG, "Content provider dead retrieving " + uri, e);
12278             return null;
12279         } catch (Exception e) {
12280             Log.w(TAG, "Exception while determining type of " + uri, e);
12281             return null;
12282         } finally {
12283             // We need to clear the identity to call removeContentProviderExternalUnchecked
12284             if (!clearedIdentity) {
12285                 ident = Binder.clearCallingIdentity();
12286             }
12287             try {
12288                 if (holder != null) {
12289                     removeContentProviderExternalUnchecked(name, null, userId);
12290                 }
12291             } finally {
12292                 Binder.restoreCallingIdentity(ident);
12293             }
12294         }
12295
12296         return null;
12297     }
12298
12299     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
12300         if (UserHandle.getUserId(callingUid) == userId) {
12301             return true;
12302         }
12303         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
12304                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
12305                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
12306                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
12307                 return true;
12308         }
12309         return false;
12310     }
12311
12312     // =========================================================
12313     // GLOBAL MANAGEMENT
12314     // =========================================================
12315
12316     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
12317             boolean isolated, int isolatedUid) {
12318         String proc = customProcess != null ? customProcess : info.processName;
12319         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12320         final int userId = UserHandle.getUserId(info.uid);
12321         int uid = info.uid;
12322         if (isolated) {
12323             if (isolatedUid == 0) {
12324                 int stepsLeft = LAST_ISOLATED_UID - FIRST_ISOLATED_UID + 1;
12325                 while (true) {
12326                     if (mNextIsolatedProcessUid < FIRST_ISOLATED_UID
12327                             || mNextIsolatedProcessUid > LAST_ISOLATED_UID) {
12328                         mNextIsolatedProcessUid = FIRST_ISOLATED_UID;
12329                     }
12330                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
12331                     mNextIsolatedProcessUid++;
12332                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
12333                         // No process for this uid, use it.
12334                         break;
12335                     }
12336                     stepsLeft--;
12337                     if (stepsLeft <= 0) {
12338                         return null;
12339                     }
12340                 }
12341             } else {
12342                 // Special case for startIsolatedProcess (internal only), where
12343                 // the uid of the isolated process is specified by the caller.
12344                 uid = isolatedUid;
12345             }
12346             getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
12347
12348             // Register the isolated UID with this application so BatteryStats knows to
12349             // attribute resource usage to the application.
12350             //
12351             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
12352             // about the process state of the isolated UID *before* it is registered with the
12353             // owning application.
12354             mBatteryStatsService.addIsolatedUid(uid, info.uid);
12355         }
12356         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
12357         if (!mBooted && !mBooting
12358                 && userId == UserHandle.USER_SYSTEM
12359                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12360             r.persistent = true;
12361             r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12362         }
12363         addProcessNameLocked(r);
12364         return r;
12365     }
12366
12367     private boolean uidOnBackgroundWhitelist(final int uid) {
12368         final int appId = UserHandle.getAppId(uid);
12369         final int[] whitelist = mBackgroundAppIdWhitelist;
12370         final int N = whitelist.length;
12371         for (int i = 0; i < N; i++) {
12372             if (appId == whitelist[i]) {
12373                 return true;
12374             }
12375         }
12376         return false;
12377     }
12378
12379     @Override
12380     public void backgroundWhitelistUid(final int uid) {
12381         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12382             throw new SecurityException("Only the OS may call backgroundWhitelistUid()");
12383         }
12384
12385         if (DEBUG_BACKGROUND_CHECK) {
12386             Slog.i(TAG, "Adding uid " + uid + " to bg uid whitelist");
12387         }
12388         synchronized (this) {
12389             final int N = mBackgroundAppIdWhitelist.length;
12390             int[] newList = new int[N+1];
12391             System.arraycopy(mBackgroundAppIdWhitelist, 0, newList, 0, N);
12392             newList[N] = UserHandle.getAppId(uid);
12393             mBackgroundAppIdWhitelist = newList;
12394         }
12395     }
12396
12397     final ProcessRecord addAppLocked(ApplicationInfo info, String customProcess, boolean isolated,
12398             String abiOverride) {
12399         ProcessRecord app;
12400         if (!isolated) {
12401             app = getProcessRecordLocked(customProcess != null ? customProcess : info.processName,
12402                     info.uid, true);
12403         } else {
12404             app = null;
12405         }
12406
12407         if (app == null) {
12408             app = newProcessRecordLocked(info, customProcess, isolated, 0);
12409             updateLruProcessLocked(app, false, null);
12410             updateOomAdjLocked();
12411         }
12412
12413         // This package really, really can not be stopped.
12414         try {
12415             AppGlobals.getPackageManager().setPackageStoppedState(
12416                     info.packageName, false, UserHandle.getUserId(app.uid));
12417         } catch (RemoteException e) {
12418         } catch (IllegalArgumentException e) {
12419             Slog.w(TAG, "Failed trying to unstop package "
12420                     + info.packageName + ": " + e);
12421         }
12422
12423         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
12424             app.persistent = true;
12425             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
12426         }
12427         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
12428             mPersistentStartingProcesses.add(app);
12429             startProcessLocked(app, "added application",
12430                     customProcess != null ? customProcess : app.processName, abiOverride,
12431                     null /* entryPoint */, null /* entryPointArgs */);
12432         }
12433
12434         return app;
12435     }
12436
12437     public void unhandledBack() {
12438         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
12439                 "unhandledBack()");
12440
12441         synchronized(this) {
12442             final long origId = Binder.clearCallingIdentity();
12443             try {
12444                 getFocusedStack().unhandledBackLocked();
12445             } finally {
12446                 Binder.restoreCallingIdentity(origId);
12447             }
12448         }
12449     }
12450
12451     public ParcelFileDescriptor openContentUri(String uriString) throws RemoteException {
12452         enforceNotIsolatedCaller("openContentUri");
12453         final int userId = UserHandle.getCallingUserId();
12454         final Uri uri = Uri.parse(uriString);
12455         String name = uri.getAuthority();
12456         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
12457         ParcelFileDescriptor pfd = null;
12458         if (cph != null) {
12459             // We record the binder invoker's uid in thread-local storage before
12460             // going to the content provider to open the file.  Later, in the code
12461             // that handles all permissions checks, we look for this uid and use
12462             // that rather than the Activity Manager's own uid.  The effect is that
12463             // we do the check against the caller's permissions even though it looks
12464             // to the content provider like the Activity Manager itself is making
12465             // the request.
12466             Binder token = new Binder();
12467             sCallerIdentity.set(new Identity(
12468                     token, Binder.getCallingPid(), Binder.getCallingUid()));
12469             try {
12470                 pfd = cph.provider.openFile(null, uri, "r", null, token);
12471             } catch (FileNotFoundException e) {
12472                 // do nothing; pfd will be returned null
12473             } finally {
12474                 // Ensure that whatever happens, we clean up the identity state
12475                 sCallerIdentity.remove();
12476                 // Ensure we're done with the provider.
12477                 removeContentProviderExternalUnchecked(name, null, userId);
12478             }
12479         } else {
12480             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
12481         }
12482         return pfd;
12483     }
12484
12485     // Actually is sleeping or shutting down or whatever else in the future
12486     // is an inactive state.
12487     boolean isSleepingOrShuttingDownLocked() {
12488         return isSleepingLocked() || mShuttingDown;
12489     }
12490
12491     boolean isShuttingDownLocked() {
12492         return mShuttingDown;
12493     }
12494
12495     boolean isSleepingLocked() {
12496         return mSleeping;
12497     }
12498
12499     void onWakefulnessChanged(int wakefulness) {
12500         synchronized(this) {
12501             boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12502             boolean isAwake = wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
12503             mWakefulness = wakefulness;
12504
12505             if (wasAwake != isAwake) {
12506                 // Also update state in a special way for running foreground services UI.
12507                 mServices.updateScreenStateLocked(isAwake);
12508                 sendNotifyVrManagerOfSleepState(!isAwake);
12509             }
12510         }
12511     }
12512
12513     void finishRunningVoiceLocked() {
12514         if (mRunningVoice != null) {
12515             mRunningVoice = null;
12516             mVoiceWakeLock.release();
12517             updateSleepIfNeededLocked();
12518         }
12519     }
12520
12521     void startTimeTrackingFocusedActivityLocked() {
12522         final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
12523         if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
12524             mCurAppTimeTracker.start(resumedActivity.packageName);
12525         }
12526     }
12527
12528     void updateSleepIfNeededLocked() {
12529         final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
12530         final boolean wasSleeping = mSleeping;
12531
12532         if (!shouldSleep) {
12533             // If wasSleeping is true, we need to wake up activity manager state from when
12534             // we started sleeping. In either case, we need to apply the sleep tokens, which
12535             // will wake up stacks or put them to sleep as appropriate.
12536             if (wasSleeping) {
12537                 mSleeping = false;
12538                 startTimeTrackingFocusedActivityLocked();
12539                 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
12540                 mStackSupervisor.comeOutOfSleepIfNeededLocked();
12541             }
12542             mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
12543             if (wasSleeping) {
12544                 updateOomAdjLocked();
12545             }
12546         } else if (!mSleeping && shouldSleep) {
12547             mSleeping = true;
12548             if (mCurAppTimeTracker != null) {
12549                 mCurAppTimeTracker.stop();
12550             }
12551             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
12552             mStackSupervisor.goingToSleepLocked();
12553             updateOomAdjLocked();
12554         }
12555     }
12556
12557     /** Pokes the task persister. */
12558     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
12559         mRecentTasks.notifyTaskPersisterLocked(task, flush);
12560     }
12561
12562     /**
12563      * Notifies all listeners when the pinned stack animation starts.
12564      */
12565     @Override
12566     public void notifyPinnedStackAnimationStarted() {
12567         mTaskChangeNotificationController.notifyPinnedStackAnimationStarted();
12568     }
12569
12570     /**
12571      * Notifies all listeners when the pinned stack animation ends.
12572      */
12573     @Override
12574     public void notifyPinnedStackAnimationEnded() {
12575         mTaskChangeNotificationController.notifyPinnedStackAnimationEnded();
12576     }
12577
12578     @Override
12579     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
12580         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
12581     }
12582
12583     @Override
12584     public boolean shutdown(int timeout) {
12585         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
12586                 != PackageManager.PERMISSION_GRANTED) {
12587             throw new SecurityException("Requires permission "
12588                     + android.Manifest.permission.SHUTDOWN);
12589         }
12590
12591         boolean timedout = false;
12592
12593         synchronized(this) {
12594             mShuttingDown = true;
12595             mStackSupervisor.prepareForShutdownLocked();
12596             updateEventDispatchingLocked();
12597             timedout = mStackSupervisor.shutdownLocked(timeout);
12598         }
12599
12600         mAppOpsService.shutdown();
12601         if (mUsageStatsService != null) {
12602             mUsageStatsService.prepareShutdown();
12603         }
12604         mBatteryStatsService.shutdown();
12605         synchronized (this) {
12606             mProcessStats.shutdownLocked();
12607             notifyTaskPersisterLocked(null, true);
12608         }
12609
12610         return timedout;
12611     }
12612
12613     public final void activitySlept(IBinder token) {
12614         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
12615
12616         final long origId = Binder.clearCallingIdentity();
12617
12618         synchronized (this) {
12619             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12620             if (r != null) {
12621                 mStackSupervisor.activitySleptLocked(r);
12622             }
12623         }
12624
12625         Binder.restoreCallingIdentity(origId);
12626     }
12627
12628     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
12629         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
12630         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
12631         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
12632             boolean wasRunningVoice = mRunningVoice != null;
12633             mRunningVoice = session;
12634             if (!wasRunningVoice) {
12635                 mVoiceWakeLock.acquire();
12636                 updateSleepIfNeededLocked();
12637             }
12638         }
12639     }
12640
12641     private void updateEventDispatchingLocked() {
12642         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
12643     }
12644
12645     @Override
12646     public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
12647         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
12648                 != PackageManager.PERMISSION_GRANTED) {
12649             throw new SecurityException("Requires permission "
12650                     + android.Manifest.permission.DEVICE_POWER);
12651         }
12652
12653         synchronized(this) {
12654             long ident = Binder.clearCallingIdentity();
12655             try {
12656                 mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
12657             } finally {
12658                 Binder.restoreCallingIdentity(ident);
12659             }
12660         }
12661         sendNotifyVrManagerOfKeyguardState(showing);
12662     }
12663
12664     @Override
12665     public void notifyLockedProfile(@UserIdInt int userId) {
12666         try {
12667             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
12668                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
12669             }
12670         } catch (RemoteException ex) {
12671             throw new SecurityException("Fail to check is caller a privileged app", ex);
12672         }
12673
12674         synchronized (this) {
12675             final long ident = Binder.clearCallingIdentity();
12676             try {
12677                 if (mUserController.shouldConfirmCredentials(userId)) {
12678                     if (mKeyguardController.isKeyguardLocked()) {
12679                         // Showing launcher to avoid user entering credential twice.
12680                         final int currentUserId = mUserController.getCurrentUserIdLocked();
12681                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
12682                     }
12683                     mStackSupervisor.lockAllProfileTasks(userId);
12684                 }
12685             } finally {
12686                 Binder.restoreCallingIdentity(ident);
12687             }
12688         }
12689     }
12690
12691     @Override
12692     public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
12693         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
12694         synchronized (this) {
12695             final long ident = Binder.clearCallingIdentity();
12696             try {
12697                 mActivityStarter.startConfirmCredentialIntent(intent, options);
12698             } finally {
12699                 Binder.restoreCallingIdentity(ident);
12700             }
12701         }
12702     }
12703
12704     @Override
12705     public void stopAppSwitches() {
12706         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12707                 != PackageManager.PERMISSION_GRANTED) {
12708             throw new SecurityException("viewquires permission "
12709                     + android.Manifest.permission.STOP_APP_SWITCHES);
12710         }
12711
12712         synchronized(this) {
12713             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
12714                     + APP_SWITCH_DELAY_TIME;
12715             mDidAppSwitch = false;
12716             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12717             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
12718             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
12719         }
12720     }
12721
12722     public void resumeAppSwitches() {
12723         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
12724                 != PackageManager.PERMISSION_GRANTED) {
12725             throw new SecurityException("Requires permission "
12726                     + android.Manifest.permission.STOP_APP_SWITCHES);
12727         }
12728
12729         synchronized(this) {
12730             // Note that we don't execute any pending app switches... we will
12731             // let those wait until either the timeout, or the next start
12732             // activity request.
12733             mAppSwitchesAllowedTime = 0;
12734         }
12735     }
12736
12737     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
12738             int callingPid, int callingUid, String name) {
12739         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
12740             return true;
12741         }
12742
12743         int perm = checkComponentPermission(
12744                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
12745                 sourceUid, -1, true);
12746         if (perm == PackageManager.PERMISSION_GRANTED) {
12747             return true;
12748         }
12749
12750         // If the actual IPC caller is different from the logical source, then
12751         // also see if they are allowed to control app switches.
12752         if (callingUid != -1 && callingUid != sourceUid) {
12753             perm = checkComponentPermission(
12754                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12755                     callingUid, -1, true);
12756             if (perm == PackageManager.PERMISSION_GRANTED) {
12757                 return true;
12758             }
12759         }
12760
12761         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12762         return false;
12763     }
12764
12765     public void setDebugApp(String packageName, boolean waitForDebugger,
12766             boolean persistent) {
12767         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12768                 "setDebugApp()");
12769
12770         long ident = Binder.clearCallingIdentity();
12771         try {
12772             // Note that this is not really thread safe if there are multiple
12773             // callers into it at the same time, but that's not a situation we
12774             // care about.
12775             if (persistent) {
12776                 final ContentResolver resolver = mContext.getContentResolver();
12777                 Settings.Global.putString(
12778                     resolver, Settings.Global.DEBUG_APP,
12779                     packageName);
12780                 Settings.Global.putInt(
12781                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12782                     waitForDebugger ? 1 : 0);
12783             }
12784
12785             synchronized (this) {
12786                 if (!persistent) {
12787                     mOrigDebugApp = mDebugApp;
12788                     mOrigWaitForDebugger = mWaitForDebugger;
12789                 }
12790                 mDebugApp = packageName;
12791                 mWaitForDebugger = waitForDebugger;
12792                 mDebugTransient = !persistent;
12793                 if (packageName != null) {
12794                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12795                             false, UserHandle.USER_ALL, "set debug app");
12796                 }
12797             }
12798         } finally {
12799             Binder.restoreCallingIdentity(ident);
12800         }
12801     }
12802
12803     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12804         synchronized (this) {
12805             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12806             if (!isDebuggable) {
12807                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12808                     throw new SecurityException("Process not debuggable: " + app.packageName);
12809                 }
12810             }
12811
12812             mTrackAllocationApp = processName;
12813         }
12814     }
12815
12816     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12817         synchronized (this) {
12818             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12819             if (!isDebuggable) {
12820                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12821                     throw new SecurityException("Process not debuggable: " + app.packageName);
12822                 }
12823             }
12824             mProfileApp = processName;
12825
12826             if (mProfilerInfo != null) {
12827                 if (mProfilerInfo.profileFd != null) {
12828                     try {
12829                         mProfilerInfo.profileFd.close();
12830                     } catch (IOException e) {
12831                     }
12832                 }
12833             }
12834             mProfilerInfo = new ProfilerInfo(profilerInfo);
12835             mProfileType = 0;
12836         }
12837     }
12838
12839     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12840         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12841         if (!isDebuggable) {
12842             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12843                 throw new SecurityException("Process not debuggable: " + app.packageName);
12844             }
12845         }
12846         mNativeDebuggingApp = processName;
12847     }
12848
12849     @Override
12850     public void setAlwaysFinish(boolean enabled) {
12851         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12852                 "setAlwaysFinish()");
12853
12854         long ident = Binder.clearCallingIdentity();
12855         try {
12856             Settings.Global.putInt(
12857                     mContext.getContentResolver(),
12858                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12859
12860             synchronized (this) {
12861                 mAlwaysFinishActivities = enabled;
12862             }
12863         } finally {
12864             Binder.restoreCallingIdentity(ident);
12865         }
12866     }
12867
12868     @Override
12869     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12870         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12871                 "setActivityController()");
12872         synchronized (this) {
12873             mController = controller;
12874             mControllerIsAMonkey = imAMonkey;
12875             Watchdog.getInstance().setActivityController(controller);
12876         }
12877     }
12878
12879     @Override
12880     public void setUserIsMonkey(boolean userIsMonkey) {
12881         synchronized (this) {
12882             synchronized (mPidsSelfLocked) {
12883                 final int callingPid = Binder.getCallingPid();
12884                 ProcessRecord proc = mPidsSelfLocked.get(callingPid);
12885                 if (proc == null) {
12886                     throw new SecurityException("Unknown process: " + callingPid);
12887                 }
12888                 if (proc.instr == null || proc.instr.mUiAutomationConnection == null) {
12889                     throw new SecurityException("Only an instrumentation process "
12890                             + "with a UiAutomation can call setUserIsMonkey");
12891                 }
12892             }
12893             mUserIsMonkey = userIsMonkey;
12894         }
12895     }
12896
12897     @Override
12898     public boolean isUserAMonkey() {
12899         synchronized (this) {
12900             // If there is a controller also implies the user is a monkey.
12901             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12902         }
12903     }
12904
12905     /**
12906      * @deprecated This method is only used by a few internal components and it will soon be
12907      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12908      * No new code should be calling it.
12909      */
12910     @Deprecated
12911     @Override
12912     public void requestBugReport(int bugreportType) {
12913         String extraOptions = null;
12914         switch (bugreportType) {
12915             case ActivityManager.BUGREPORT_OPTION_FULL:
12916                 // Default options.
12917                 break;
12918             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12919                 extraOptions = "bugreportplus";
12920                 break;
12921             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12922                 extraOptions = "bugreportremote";
12923                 break;
12924             case ActivityManager.BUGREPORT_OPTION_WEAR:
12925                 extraOptions = "bugreportwear";
12926                 break;
12927             case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12928                 extraOptions = "bugreporttelephony";
12929                 break;
12930             default:
12931                 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12932                         + bugreportType);
12933         }
12934         // Always log caller, even if it does not have permission to dump.
12935         String type = extraOptions == null ? "bugreport" : extraOptions;
12936         Slog.i(TAG, type + " requested by UID " + Binder.getCallingUid());
12937
12938         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12939         if (extraOptions != null) {
12940             SystemProperties.set("dumpstate.options", extraOptions);
12941         }
12942         SystemProperties.set("ctl.start", "bugreport");
12943     }
12944
12945     /**
12946      * @deprecated This method is only used by a few internal components and it will soon be
12947      * replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
12948      * No new code should be calling it.
12949      */
12950     @Deprecated
12951     @Override
12952     public void requestTelephonyBugReport(String shareTitle, String shareDescription) {
12953
12954         if (!TextUtils.isEmpty(shareTitle)) {
12955             if (shareTitle.length() > MAX_BUGREPORT_TITLE_SIZE) {
12956                 String errorStr = "shareTitle should be less than " +
12957                         MAX_BUGREPORT_TITLE_SIZE + " characters";
12958                 throw new IllegalArgumentException(errorStr);
12959             } else {
12960                 if (!TextUtils.isEmpty(shareDescription)) {
12961                     int length;
12962                     try {
12963                         length = shareDescription.getBytes("UTF-8").length;
12964                     } catch (UnsupportedEncodingException e) {
12965                         String errorStr = "shareDescription: UnsupportedEncodingException";
12966                         throw new IllegalArgumentException(errorStr);
12967                     }
12968                     if (length > SystemProperties.PROP_VALUE_MAX) {
12969                         String errorStr = "shareTitle should be less than " +
12970                                 SystemProperties.PROP_VALUE_MAX + " bytes";
12971                         throw new IllegalArgumentException(errorStr);
12972                     } else {
12973                         SystemProperties.set("dumpstate.options.description", shareDescription);
12974                     }
12975                 }
12976                 SystemProperties.set("dumpstate.options.title", shareTitle);
12977             }
12978         }
12979
12980         Slog.d(TAG, "Bugreport notification title " + shareTitle
12981                 + " description " + shareDescription);
12982         requestBugReport(ActivityManager.BUGREPORT_OPTION_TELEPHONY);
12983     }
12984
12985     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12986         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12987     }
12988
12989     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12990         if (r != null && (r.instr != null || r.usingWrapper)) {
12991             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12992         }
12993         return KEY_DISPATCHING_TIMEOUT;
12994     }
12995
12996     @Override
12997     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12998         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12999                 != PackageManager.PERMISSION_GRANTED) {
13000             throw new SecurityException("Requires permission "
13001                     + android.Manifest.permission.FILTER_EVENTS);
13002         }
13003         ProcessRecord proc;
13004         long timeout;
13005         synchronized (this) {
13006             synchronized (mPidsSelfLocked) {
13007                 proc = mPidsSelfLocked.get(pid);
13008             }
13009             timeout = getInputDispatchingTimeoutLocked(proc);
13010         }
13011
13012         if (inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
13013             return -1;
13014         }
13015
13016         return timeout;
13017     }
13018
13019     /**
13020      * Handle input dispatching timeouts.
13021      * Returns whether input dispatching should be aborted or not.
13022      */
13023     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
13024             final ActivityRecord activity, final ActivityRecord parent,
13025             final boolean aboveSystem, String reason) {
13026         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
13027                 != PackageManager.PERMISSION_GRANTED) {
13028             throw new SecurityException("Requires permission "
13029                     + android.Manifest.permission.FILTER_EVENTS);
13030         }
13031
13032         final String annotation;
13033         if (reason == null) {
13034             annotation = "Input dispatching timed out";
13035         } else {
13036             annotation = "Input dispatching timed out (" + reason + ")";
13037         }
13038
13039         if (proc != null) {
13040             synchronized (this) {
13041                 if (proc.debugging) {
13042                     return false;
13043                 }
13044
13045                 if (proc.instr != null) {
13046                     Bundle info = new Bundle();
13047                     info.putString("shortMsg", "keyDispatchingTimedOut");
13048                     info.putString("longMsg", annotation);
13049                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
13050                     return true;
13051                 }
13052             }
13053             mHandler.post(new Runnable() {
13054                 @Override
13055                 public void run() {
13056                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
13057                 }
13058             });
13059         }
13060
13061         return true;
13062     }
13063
13064     @Override
13065     public Bundle getAssistContextExtras(int requestType) {
13066         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
13067                 null, null, true /* focused */, true /* newSessionId */,
13068                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT, 0);
13069         if (pae == null) {
13070             return null;
13071         }
13072         synchronized (pae) {
13073             while (!pae.haveResult) {
13074                 try {
13075                     pae.wait();
13076                 } catch (InterruptedException e) {
13077                 }
13078             }
13079         }
13080         synchronized (this) {
13081             buildAssistBundleLocked(pae, pae.result);
13082             mPendingAssistExtras.remove(pae);
13083             mUiHandler.removeCallbacks(pae);
13084         }
13085         return pae.extras;
13086     }
13087
13088     @Override
13089     public boolean isAssistDataAllowedOnCurrentActivity() {
13090         int userId;
13091         synchronized (this) {
13092             final ActivityStack focusedStack = getFocusedStack();
13093             if (focusedStack == null || focusedStack.isAssistantStack()) {
13094                 return false;
13095             }
13096
13097             final ActivityRecord activity = focusedStack.topActivity();
13098             if (activity == null) {
13099                 return false;
13100             }
13101             userId = activity.userId;
13102         }
13103         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
13104                 Context.DEVICE_POLICY_SERVICE);
13105         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
13106     }
13107
13108     @Override
13109     public boolean showAssistFromActivity(IBinder token, Bundle args) {
13110         long ident = Binder.clearCallingIdentity();
13111         try {
13112             synchronized (this) {
13113                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
13114                 ActivityRecord top = getFocusedStack().topActivity();
13115                 if (top != caller) {
13116                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13117                             + " is not current top " + top);
13118                     return false;
13119                 }
13120                 if (!top.nowVisible) {
13121                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
13122                             + " is not visible");
13123                     return false;
13124                 }
13125             }
13126             return mAssistUtils.showSessionForActiveService(args, SHOW_SOURCE_APPLICATION, null,
13127                     token);
13128         } finally {
13129             Binder.restoreCallingIdentity(ident);
13130         }
13131     }
13132
13133     @Override
13134     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
13135             Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId) {
13136         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
13137                 activityToken, focused, newSessionId, UserHandle.getCallingUserId(), null,
13138                 PENDING_ASSIST_EXTRAS_LONG_TIMEOUT, 0) != null;
13139     }
13140
13141     @Override
13142     public boolean requestAutofillData(IResultReceiver receiver, Bundle receiverExtras,
13143             IBinder activityToken, int flags) {
13144         return enqueueAssistContext(ActivityManager.ASSIST_CONTEXT_AUTOFILL, null, null,
13145                 receiver, receiverExtras, activityToken, true, true, UserHandle.getCallingUserId(),
13146                 null, PENDING_AUTOFILL_ASSIST_STRUCTURE_TIMEOUT, flags) != null;
13147     }
13148
13149     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
13150             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
13151             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout,
13152             int flags) {
13153         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
13154                 "enqueueAssistContext()");
13155
13156         synchronized (this) {
13157             ActivityRecord activity = getFocusedStack().topActivity();
13158             if (activity == null) {
13159                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
13160                 return null;
13161             }
13162             if (activity.app == null || activity.app.thread == null) {
13163                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
13164                 return null;
13165             }
13166             if (focused) {
13167                 if (activityToken != null) {
13168                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
13169                     if (activity != caller) {
13170                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
13171                                 + " is not current top " + activity);
13172                         return null;
13173                     }
13174                 }
13175             } else {
13176                 activity = ActivityRecord.forTokenLocked(activityToken);
13177                 if (activity == null) {
13178                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
13179                             + " couldn't be found");
13180                     return null;
13181                 }
13182                 if (activity.app == null || activity.app.thread == null) {
13183                     Slog.w(TAG, "enqueueAssistContext failed: no process for " + activity);
13184                     return null;
13185                 }
13186             }
13187
13188             PendingAssistExtras pae;
13189             Bundle extras = new Bundle();
13190             if (args != null) {
13191                 extras.putAll(args);
13192             }
13193             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
13194             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
13195
13196             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
13197                     userHandle);
13198             pae.isHome = activity.isHomeActivity();
13199
13200             // Increment the sessionId if necessary
13201             if (newSessionId) {
13202                 mViSessionId++;
13203             }
13204             try {
13205                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, requestType,
13206                         mViSessionId, flags);
13207                 mPendingAssistExtras.add(pae);
13208                 mUiHandler.postDelayed(pae, timeout);
13209             } catch (RemoteException e) {
13210                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
13211                 return null;
13212             }
13213             return pae;
13214         }
13215     }
13216
13217     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
13218         IResultReceiver receiver;
13219         synchronized (this) {
13220             mPendingAssistExtras.remove(pae);
13221             receiver = pae.receiver;
13222         }
13223         if (receiver != null) {
13224             // Caller wants result sent back to them.
13225             Bundle sendBundle = new Bundle();
13226             // At least return the receiver extras
13227             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13228                     pae.receiverExtras);
13229             try {
13230                 pae.receiver.send(0, sendBundle);
13231             } catch (RemoteException e) {
13232             }
13233         }
13234     }
13235
13236     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
13237         if (result != null) {
13238             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
13239         }
13240         if (pae.hint != null) {
13241             pae.extras.putBoolean(pae.hint, true);
13242         }
13243     }
13244
13245     /** Called from an app when assist data is ready. */
13246     @Override
13247     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
13248             AssistContent content, Uri referrer) {
13249         PendingAssistExtras pae = (PendingAssistExtras)token;
13250         synchronized (pae) {
13251             pae.result = extras;
13252             pae.structure = structure;
13253             pae.content = content;
13254             if (referrer != null) {
13255                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
13256             }
13257             if (structure != null) {
13258                 structure.setHomeActivity(pae.isHome);
13259             }
13260             pae.haveResult = true;
13261             pae.notifyAll();
13262             if (pae.intent == null && pae.receiver == null) {
13263                 // Caller is just waiting for the result.
13264                 return;
13265             }
13266         }
13267         // We are now ready to launch the assist activity.
13268         IResultReceiver sendReceiver = null;
13269         Bundle sendBundle = null;
13270         synchronized (this) {
13271             buildAssistBundleLocked(pae, extras);
13272             boolean exists = mPendingAssistExtras.remove(pae);
13273             mUiHandler.removeCallbacks(pae);
13274             if (!exists) {
13275                 // Timed out.
13276                 return;
13277             }
13278             if ((sendReceiver=pae.receiver) != null) {
13279                 // Caller wants result sent back to them.
13280                 sendBundle = new Bundle();
13281                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
13282                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
13283                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
13284                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
13285                         pae.receiverExtras);
13286             }
13287         }
13288         if (sendReceiver != null) {
13289             try {
13290                 sendReceiver.send(0, sendBundle);
13291             } catch (RemoteException e) {
13292             }
13293             return;
13294         }
13295
13296         final long ident = Binder.clearCallingIdentity();
13297         try {
13298             if (TextUtils.equals(pae.intent.getAction(),
13299                     android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
13300                 pae.intent.putExtras(pae.extras);
13301                 mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
13302             } else {
13303                 pae.intent.replaceExtras(pae.extras);
13304                 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
13305                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
13306                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
13307                 closeSystemDialogs("assist");
13308
13309                 try {
13310                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
13311                 } catch (ActivityNotFoundException e) {
13312                     Slog.w(TAG, "No activity to handle assist action.", e);
13313                 }
13314             }
13315         } finally {
13316             Binder.restoreCallingIdentity(ident);
13317         }
13318     }
13319
13320     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
13321             Bundle args) {
13322         return enqueueAssistContext(requestType, intent, hint, null, null, null,
13323                 true /* focused */, true /* newSessionId */, userHandle, args,
13324                 PENDING_ASSIST_EXTRAS_TIMEOUT, 0) != null;
13325     }
13326
13327     public void registerProcessObserver(IProcessObserver observer) {
13328         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
13329                 "registerProcessObserver()");
13330         synchronized (this) {
13331             mProcessObservers.register(observer);
13332         }
13333     }
13334
13335     @Override
13336     public void unregisterProcessObserver(IProcessObserver observer) {
13337         synchronized (this) {
13338             mProcessObservers.unregister(observer);
13339         }
13340     }
13341
13342     @Override
13343     public int getUidProcessState(int uid, String callingPackage) {
13344         if (!hasUsageStatsPermission(callingPackage)) {
13345             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13346                     "getUidProcessState");
13347         }
13348
13349         synchronized (this) {
13350             UidRecord uidRec = mActiveUids.get(uid);
13351             return uidRec != null ? uidRec.curProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
13352         }
13353     }
13354
13355     @Override
13356     public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
13357             String callingPackage) {
13358         if (!hasUsageStatsPermission(callingPackage)) {
13359             enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
13360                     "registerUidObserver");
13361         }
13362         synchronized (this) {
13363             mUidObservers.register(observer, new UidObserverRegistration(Binder.getCallingUid(),
13364                     callingPackage, which, cutpoint));
13365         }
13366     }
13367
13368     @Override
13369     public void unregisterUidObserver(IUidObserver observer) {
13370         synchronized (this) {
13371             mUidObservers.unregister(observer);
13372         }
13373     }
13374
13375     @Override
13376     public boolean convertFromTranslucent(IBinder token) {
13377         final long origId = Binder.clearCallingIdentity();
13378         try {
13379             synchronized (this) {
13380                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13381                 if (r == null) {
13382                     return false;
13383                 }
13384                 final boolean translucentChanged = r.changeWindowTranslucency(true);
13385                 if (translucentChanged) {
13386                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13387                 }
13388                 mWindowManager.setAppFullscreen(token, true);
13389                 return translucentChanged;
13390             }
13391         } finally {
13392             Binder.restoreCallingIdentity(origId);
13393         }
13394     }
13395
13396     @Override
13397     public boolean convertToTranslucent(IBinder token, Bundle options) {
13398         final long origId = Binder.clearCallingIdentity();
13399         try {
13400             synchronized (this) {
13401                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13402                 if (r == null) {
13403                     return false;
13404                 }
13405                 final TaskRecord task = r.getTask();
13406                 int index = task.mActivities.lastIndexOf(r);
13407                 if (index > 0) {
13408                     ActivityRecord under = task.mActivities.get(index - 1);
13409                     under.returningOptions = ActivityOptions.fromBundle(options);
13410                 }
13411                 final boolean translucentChanged = r.changeWindowTranslucency(false);
13412                 if (translucentChanged) {
13413                     r.getStack().convertActivityToTranslucent(r);
13414                 }
13415                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
13416                 mWindowManager.setAppFullscreen(token, false);
13417                 return translucentChanged;
13418             }
13419         } finally {
13420             Binder.restoreCallingIdentity(origId);
13421         }
13422     }
13423
13424     @Override
13425     public Bundle getActivityOptions(IBinder token) {
13426         final long origId = Binder.clearCallingIdentity();
13427         try {
13428             synchronized (this) {
13429                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13430                 if (r != null) {
13431                     final ActivityOptions activityOptions = r.takeOptionsLocked();
13432                     return activityOptions == null ? null : activityOptions.toBundle();
13433                 }
13434                 return null;
13435             }
13436         } finally {
13437             Binder.restoreCallingIdentity(origId);
13438         }
13439     }
13440
13441     @Override
13442     public void setImmersive(IBinder token, boolean immersive) {
13443         synchronized(this) {
13444             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
13445             if (r == null) {
13446                 throw new IllegalArgumentException();
13447             }
13448             r.immersive = immersive;
13449
13450             // update associated state if we're frontmost
13451             if (r == mStackSupervisor.getResumedActivityLocked()) {
13452                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
13453                 applyUpdateLockStateLocked(r);
13454             }
13455         }
13456     }
13457
13458     @Override
13459     public boolean isImmersive(IBinder token) {
13460         synchronized (this) {
13461             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13462             if (r == null) {
13463                 throw new IllegalArgumentException();
13464             }
13465             return r.immersive;
13466         }
13467     }
13468
13469     @Override
13470     public void setVrThread(int tid) {
13471         enforceSystemHasVrFeature();
13472         synchronized (this) {
13473             synchronized (mPidsSelfLocked) {
13474                 final int pid = Binder.getCallingPid();
13475                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13476                 mVrController.setVrThreadLocked(tid, pid, proc);
13477             }
13478         }
13479     }
13480
13481     @Override
13482     public void setPersistentVrThread(int tid) {
13483         if (checkCallingPermission(permission.RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
13484             final String msg = "Permission Denial: setPersistentVrThread() from pid="
13485                     + Binder.getCallingPid()
13486                     + ", uid=" + Binder.getCallingUid()
13487                     + " requires " + permission.RESTRICTED_VR_ACCESS;
13488             Slog.w(TAG, msg);
13489             throw new SecurityException(msg);
13490         }
13491         enforceSystemHasVrFeature();
13492         synchronized (this) {
13493             synchronized (mPidsSelfLocked) {
13494                 final int pid = Binder.getCallingPid();
13495                 final ProcessRecord proc = mPidsSelfLocked.get(pid);
13496                 mVrController.setPersistentVrThreadLocked(tid, pid, proc);
13497             }
13498         }
13499     }
13500
13501     /**
13502      * Schedule the given thread a normal scheduling priority.
13503      *
13504      * @param tid the tid of the thread to adjust the scheduling of.
13505      * @param suppressLogs {@code true} if any error logging should be disabled.
13506      *
13507      * @return {@code true} if this succeeded.
13508      */
13509     static boolean scheduleAsRegularPriority(int tid, boolean suppressLogs) {
13510         try {
13511             Process.setThreadScheduler(tid, Process.SCHED_OTHER, 0);
13512             return true;
13513         } catch (IllegalArgumentException e) {
13514             if (!suppressLogs) {
13515                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13516             }
13517         } catch (SecurityException e) {
13518             if (!suppressLogs) {
13519                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13520             }
13521         }
13522         return false;
13523     }
13524
13525     /**
13526      * Schedule the given thread an FIFO scheduling priority.
13527      *
13528      * @param tid the tid of the thread to adjust the scheduling of.
13529      * @param suppressLogs {@code true} if any error logging should be disabled.
13530      *
13531      * @return {@code true} if this succeeded.
13532      */
13533     static boolean scheduleAsFifoPriority(int tid, boolean suppressLogs) {
13534         try {
13535             Process.setThreadScheduler(tid, Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
13536             return true;
13537         } catch (IllegalArgumentException e) {
13538             if (!suppressLogs) {
13539                 Slog.w(TAG, "Failed to set scheduling policy, thread does not exist:\n" + e);
13540             }
13541         } catch (SecurityException e) {
13542             if (!suppressLogs) {
13543                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
13544             }
13545         }
13546         return false;
13547     }
13548
13549     /**
13550      * Check that we have the features required for VR-related API calls, and throw an exception if
13551      * not.
13552      */
13553     private void enforceSystemHasVrFeature() {
13554         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13555             throw new UnsupportedOperationException("VR mode not supported on this device!");
13556         }
13557     }
13558
13559     @Override
13560     public void setRenderThread(int tid) {
13561         synchronized (this) {
13562             ProcessRecord proc;
13563             int pid = Binder.getCallingPid();
13564             if (pid == Process.myPid()) {
13565                 demoteSystemServerRenderThread(tid);
13566                 return;
13567             }
13568             synchronized (mPidsSelfLocked) {
13569                 proc = mPidsSelfLocked.get(pid);
13570                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
13571                     // ensure the tid belongs to the process
13572                     if (!isThreadInProcess(pid, tid)) {
13573                         throw new IllegalArgumentException(
13574                             "Render thread does not belong to process");
13575                     }
13576                     proc.renderThreadTid = tid;
13577                     if (DEBUG_OOM_ADJ) {
13578                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
13579                     }
13580                     // promote to FIFO now
13581                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
13582                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
13583                         if (mUseFifoUiScheduling) {
13584                             setThreadScheduler(proc.renderThreadTid,
13585                                 SCHED_FIFO | SCHED_RESET_ON_FORK, 1);
13586                         } else {
13587                             setThreadPriority(proc.renderThreadTid, TOP_APP_PRIORITY_BOOST);
13588                         }
13589                     }
13590                 } else {
13591                     if (DEBUG_OOM_ADJ) {
13592                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
13593                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
13594                                mUseFifoUiScheduling);
13595                     }
13596                 }
13597             }
13598         }
13599     }
13600
13601     /**
13602      * We only use RenderThread in system_server to store task snapshots to the disk, which should
13603      * happen in the background. Thus, demote render thread from system_server to a lower priority.
13604      *
13605      * @param tid the tid of the RenderThread
13606      */
13607     private void demoteSystemServerRenderThread(int tid) {
13608         setThreadPriority(tid, Process.THREAD_PRIORITY_BACKGROUND);
13609     }
13610
13611     @Override
13612     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
13613         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13614             throw new UnsupportedOperationException("VR mode not supported on this device!");
13615         }
13616
13617         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13618
13619         ActivityRecord r;
13620         synchronized (this) {
13621             r = ActivityRecord.isInStackLocked(token);
13622         }
13623
13624         if (r == null) {
13625             throw new IllegalArgumentException();
13626         }
13627
13628         int err;
13629         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
13630                 VrManagerInternal.NO_ERROR) {
13631             return err;
13632         }
13633
13634         synchronized(this) {
13635             r.requestedVrComponent = (enabled) ? packageName : null;
13636
13637             // Update associated state if this activity is currently focused
13638             if (r == mStackSupervisor.getResumedActivityLocked()) {
13639                 applyUpdateVrModeLocked(r);
13640             }
13641             return 0;
13642         }
13643     }
13644
13645     @Override
13646     public boolean isVrModePackageEnabled(ComponentName packageName) {
13647         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
13648             throw new UnsupportedOperationException("VR mode not supported on this device!");
13649         }
13650
13651         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
13652
13653         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
13654                 VrManagerInternal.NO_ERROR;
13655     }
13656
13657     public boolean isTopActivityImmersive() {
13658         enforceNotIsolatedCaller("startActivity");
13659         synchronized (this) {
13660             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
13661             return (r != null) ? r.immersive : false;
13662         }
13663     }
13664
13665     /**
13666      * @return whether the system should disable UI modes incompatible with VR mode.
13667      */
13668     boolean shouldDisableNonVrUiLocked() {
13669         return mVrController.shouldDisableNonVrUiLocked();
13670     }
13671
13672     @Override
13673     public boolean isTopOfTask(IBinder token) {
13674         synchronized (this) {
13675             ActivityRecord r = ActivityRecord.isInStackLocked(token);
13676             if (r == null) {
13677                 throw new IllegalArgumentException();
13678             }
13679             return r.getTask().getTopActivity() == r;
13680         }
13681     }
13682
13683     @Override
13684     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
13685         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
13686             String msg = "Permission Denial: setHasTopUi() from pid="
13687                     + Binder.getCallingPid()
13688                     + ", uid=" + Binder.getCallingUid()
13689                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
13690             Slog.w(TAG, msg);
13691             throw new SecurityException(msg);
13692         }
13693         final int pid = Binder.getCallingPid();
13694         final long origId = Binder.clearCallingIdentity();
13695         try {
13696             synchronized (this) {
13697                 boolean changed = false;
13698                 ProcessRecord pr;
13699                 synchronized (mPidsSelfLocked) {
13700                     pr = mPidsSelfLocked.get(pid);
13701                     if (pr == null) {
13702                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
13703                         return;
13704                     }
13705                     if (pr.hasTopUi != hasTopUi) {
13706                         if (DEBUG_OOM_ADJ) {
13707                             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
13708                         }
13709                         pr.hasTopUi = hasTopUi;
13710                         changed = true;
13711                     }
13712                 }
13713                 if (changed) {
13714                     updateOomAdjLocked(pr, true);
13715                 }
13716             }
13717         } finally {
13718             Binder.restoreCallingIdentity(origId);
13719         }
13720     }
13721
13722     public final void enterSafeMode() {
13723         synchronized(this) {
13724             // It only makes sense to do this before the system is ready
13725             // and started launching other packages.
13726             if (!mSystemReady) {
13727                 try {
13728                     AppGlobals.getPackageManager().enterSafeMode();
13729                 } catch (RemoteException e) {
13730                 }
13731             }
13732
13733             mSafeMode = true;
13734         }
13735     }
13736
13737     public final void showSafeModeOverlay() {
13738         View v = LayoutInflater.from(mContext).inflate(
13739                 com.android.internal.R.layout.safe_mode, null);
13740         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
13741         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
13742         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
13743         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
13744         lp.gravity = Gravity.BOTTOM | Gravity.START;
13745         lp.format = v.getBackground().getOpacity();
13746         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
13747                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
13748         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
13749         ((WindowManager)mContext.getSystemService(
13750                 Context.WINDOW_SERVICE)).addView(v, lp);
13751     }
13752
13753     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
13754         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13755             return;
13756         }
13757         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13758         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13759         synchronized (stats) {
13760             if (mBatteryStatsService.isOnBattery()) {
13761                 mBatteryStatsService.enforceCallingPermission();
13762                 int MY_UID = Binder.getCallingUid();
13763                 final int uid;
13764                 if (sender == null) {
13765                     uid = sourceUid;
13766                 } else {
13767                     uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13768                 }
13769                 BatteryStatsImpl.Uid.Pkg pkg =
13770                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
13771                             sourcePkg != null ? sourcePkg : rec.key.packageName);
13772                 pkg.noteWakeupAlarmLocked(tag);
13773             }
13774         }
13775     }
13776
13777     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
13778         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13779             return;
13780         }
13781         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13782         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13783         synchronized (stats) {
13784             mBatteryStatsService.enforceCallingPermission();
13785             int MY_UID = Binder.getCallingUid();
13786             final int uid;
13787             if (sender == null) {
13788                 uid = sourceUid;
13789             } else {
13790                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13791             }
13792             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
13793         }
13794     }
13795
13796     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
13797         if (sender != null && !(sender instanceof PendingIntentRecord)) {
13798             return;
13799         }
13800         final PendingIntentRecord rec = (PendingIntentRecord)sender;
13801         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13802         synchronized (stats) {
13803             mBatteryStatsService.enforceCallingPermission();
13804             int MY_UID = Binder.getCallingUid();
13805             final int uid;
13806             if (sender == null) {
13807                 uid = sourceUid;
13808             } else {
13809                 uid = rec.uid == MY_UID ? SYSTEM_UID : rec.uid;
13810             }
13811             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
13812         }
13813     }
13814
13815     public boolean killPids(int[] pids, String pReason, boolean secure) {
13816         if (Binder.getCallingUid() != SYSTEM_UID) {
13817             throw new SecurityException("killPids only available to the system");
13818         }
13819         String reason = (pReason == null) ? "Unknown" : pReason;
13820         // XXX Note: don't acquire main activity lock here, because the window
13821         // manager calls in with its locks held.
13822
13823         boolean killed = false;
13824         synchronized (mPidsSelfLocked) {
13825             int worstType = 0;
13826             for (int i=0; i<pids.length; i++) {
13827                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13828                 if (proc != null) {
13829                     int type = proc.setAdj;
13830                     if (type > worstType) {
13831                         worstType = type;
13832                     }
13833                 }
13834             }
13835
13836             // If the worst oom_adj is somewhere in the cached proc LRU range,
13837             // then constrain it so we will kill all cached procs.
13838             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
13839                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
13840                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
13841             }
13842
13843             // If this is not a secure call, don't let it kill processes that
13844             // are important.
13845             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
13846                 worstType = ProcessList.SERVICE_ADJ;
13847             }
13848
13849             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
13850             for (int i=0; i<pids.length; i++) {
13851                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
13852                 if (proc == null) {
13853                     continue;
13854                 }
13855                 int adj = proc.setAdj;
13856                 if (adj >= worstType && !proc.killedByAm) {
13857                     proc.kill(reason, true);
13858                     killed = true;
13859                 }
13860             }
13861         }
13862         return killed;
13863     }
13864
13865     @Override
13866     public void killUid(int appId, int userId, String reason) {
13867         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13868         synchronized (this) {
13869             final long identity = Binder.clearCallingIdentity();
13870             try {
13871                 killPackageProcessesLocked(null, appId, userId,
13872                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13873                         reason != null ? reason : "kill uid");
13874             } finally {
13875                 Binder.restoreCallingIdentity(identity);
13876             }
13877         }
13878     }
13879
13880     @Override
13881     public boolean killProcessesBelowForeground(String reason) {
13882         if (Binder.getCallingUid() != SYSTEM_UID) {
13883             throw new SecurityException("killProcessesBelowForeground() only available to system");
13884         }
13885
13886         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13887     }
13888
13889     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13890         if (Binder.getCallingUid() != SYSTEM_UID) {
13891             throw new SecurityException("killProcessesBelowAdj() only available to system");
13892         }
13893
13894         boolean killed = false;
13895         synchronized (mPidsSelfLocked) {
13896             final int size = mPidsSelfLocked.size();
13897             for (int i = 0; i < size; i++) {
13898                 final int pid = mPidsSelfLocked.keyAt(i);
13899                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13900                 if (proc == null) continue;
13901
13902                 final int adj = proc.setAdj;
13903                 if (adj > belowAdj && !proc.killedByAm) {
13904                     proc.kill(reason, true);
13905                     killed = true;
13906                 }
13907             }
13908         }
13909         return killed;
13910     }
13911
13912     @Override
13913     public void hang(final IBinder who, boolean allowRestart) {
13914         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13915                 != PackageManager.PERMISSION_GRANTED) {
13916             throw new SecurityException("Requires permission "
13917                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13918         }
13919
13920         final IBinder.DeathRecipient death = new DeathRecipient() {
13921             @Override
13922             public void binderDied() {
13923                 synchronized (this) {
13924                     notifyAll();
13925                 }
13926             }
13927         };
13928
13929         try {
13930             who.linkToDeath(death, 0);
13931         } catch (RemoteException e) {
13932             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13933             return;
13934         }
13935
13936         synchronized (this) {
13937             Watchdog.getInstance().setAllowRestart(allowRestart);
13938             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13939             synchronized (death) {
13940                 while (who.isBinderAlive()) {
13941                     try {
13942                         death.wait();
13943                     } catch (InterruptedException e) {
13944                     }
13945                 }
13946             }
13947             Watchdog.getInstance().setAllowRestart(true);
13948         }
13949     }
13950
13951     @Override
13952     public void restart() {
13953         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13954                 != PackageManager.PERMISSION_GRANTED) {
13955             throw new SecurityException("Requires permission "
13956                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13957         }
13958
13959         Log.i(TAG, "Sending shutdown broadcast...");
13960
13961         BroadcastReceiver br = new BroadcastReceiver() {
13962             @Override public void onReceive(Context context, Intent intent) {
13963                 // Now the broadcast is done, finish up the low-level shutdown.
13964                 Log.i(TAG, "Shutting down activity manager...");
13965                 shutdown(10000);
13966                 Log.i(TAG, "Shutdown complete, restarting!");
13967                 killProcess(myPid());
13968                 System.exit(10);
13969             }
13970         };
13971
13972         // First send the high-level shut down broadcast.
13973         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13974         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13975         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13976         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13977         mContext.sendOrderedBroadcastAsUser(intent,
13978                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13979         */
13980         br.onReceive(mContext, intent);
13981     }
13982
13983     private long getLowRamTimeSinceIdle(long now) {
13984         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13985     }
13986
13987     @Override
13988     public void performIdleMaintenance() {
13989         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13990                 != PackageManager.PERMISSION_GRANTED) {
13991             throw new SecurityException("Requires permission "
13992                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13993         }
13994
13995         synchronized (this) {
13996             final long now = SystemClock.uptimeMillis();
13997             final long timeSinceLastIdle = now - mLastIdleTime;
13998             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13999             mLastIdleTime = now;
14000             mLowRamTimeSinceLastIdle = 0;
14001             if (mLowRamStartTime != 0) {
14002                 mLowRamStartTime = now;
14003             }
14004
14005             StringBuilder sb = new StringBuilder(128);
14006             sb.append("Idle maintenance over ");
14007             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14008             sb.append(" low RAM for ");
14009             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14010             Slog.i(TAG, sb.toString());
14011
14012             // If at least 1/3 of our time since the last idle period has been spent
14013             // with RAM low, then we want to kill processes.
14014             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
14015
14016             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14017                 ProcessRecord proc = mLruProcesses.get(i);
14018                 if (proc.notCachedSinceIdle) {
14019                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
14020                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
14021                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
14022                         if (doKilling && proc.initialIdlePss != 0
14023                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
14024                             sb = new StringBuilder(128);
14025                             sb.append("Kill");
14026                             sb.append(proc.processName);
14027                             sb.append(" in idle maint: pss=");
14028                             sb.append(proc.lastPss);
14029                             sb.append(", swapPss=");
14030                             sb.append(proc.lastSwapPss);
14031                             sb.append(", initialPss=");
14032                             sb.append(proc.initialIdlePss);
14033                             sb.append(", period=");
14034                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
14035                             sb.append(", lowRamPeriod=");
14036                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
14037                             Slog.wtfQuiet(TAG, sb.toString());
14038                             proc.kill("idle maint (pss " + proc.lastPss
14039                                     + " from " + proc.initialIdlePss + ")", true);
14040                         }
14041                     }
14042                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
14043                         && proc.setProcState >= ActivityManager.PROCESS_STATE_PERSISTENT) {
14044                     proc.notCachedSinceIdle = true;
14045                     proc.initialIdlePss = 0;
14046                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
14047                             mTestPssMode, isSleepingLocked(), now);
14048                 }
14049             }
14050
14051             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
14052             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
14053         }
14054     }
14055
14056     @Override
14057     public void sendIdleJobTrigger() {
14058         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14059                 != PackageManager.PERMISSION_GRANTED) {
14060             throw new SecurityException("Requires permission "
14061                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14062         }
14063
14064         final long ident = Binder.clearCallingIdentity();
14065         try {
14066             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
14067                     .setPackage("android")
14068                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14069             broadcastIntent(null, intent, null, null, 0, null, null, null,
14070                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
14071         } finally {
14072             Binder.restoreCallingIdentity(ident);
14073         }
14074     }
14075
14076     private void retrieveSettings() {
14077         final ContentResolver resolver = mContext.getContentResolver();
14078         final boolean freeformWindowManagement =
14079                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
14080                         || Settings.Global.getInt(
14081                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
14082
14083         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext);
14084         final boolean supportsPictureInPicture = supportsMultiWindow &&
14085                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
14086         final boolean supportsSplitScreenMultiWindow =
14087                 ActivityManager.supportsSplitScreenMultiWindow(mContext);
14088         final boolean supportsMultiDisplay = mContext.getPackageManager()
14089                 .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS);
14090         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
14091         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
14092         final boolean alwaysFinishActivities =
14093                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
14094         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
14095         final boolean forceResizable = Settings.Global.getInt(
14096                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
14097         final long waitForNetworkTimeoutMs = Settings.Global.getLong(resolver,
14098                 NETWORK_ACCESS_TIMEOUT_MS, NETWORK_ACCESS_TIMEOUT_DEFAULT_MS);
14099         final boolean supportsLeanbackOnly =
14100                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
14101
14102         // Transfer any global setting for forcing RTL layout, into a System Property
14103         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
14104
14105         final Configuration configuration = new Configuration();
14106         Settings.System.getConfiguration(resolver, configuration);
14107         if (forceRtl) {
14108             // This will take care of setting the correct layout direction flags
14109             configuration.setLayoutDirection(configuration.locale);
14110         }
14111
14112         synchronized (this) {
14113             mDebugApp = mOrigDebugApp = debugApp;
14114             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
14115             mAlwaysFinishActivities = alwaysFinishActivities;
14116             mSupportsLeanbackOnly = supportsLeanbackOnly;
14117             mForceResizableActivities = forceResizable;
14118             final boolean multiWindowFormEnabled = freeformWindowManagement
14119                     || supportsSplitScreenMultiWindow
14120                     || supportsPictureInPicture
14121                     || supportsMultiDisplay;
14122             if ((supportsMultiWindow || forceResizable) && multiWindowFormEnabled) {
14123                 mSupportsMultiWindow = true;
14124                 mSupportsFreeformWindowManagement = freeformWindowManagement;
14125                 mSupportsSplitScreenMultiWindow = supportsSplitScreenMultiWindow;
14126                 mSupportsPictureInPicture = supportsPictureInPicture;
14127                 mSupportsMultiDisplay = supportsMultiDisplay;
14128             } else {
14129                 mSupportsMultiWindow = false;
14130                 mSupportsFreeformWindowManagement = false;
14131                 mSupportsSplitScreenMultiWindow = false;
14132                 mSupportsPictureInPicture = false;
14133                 mSupportsMultiDisplay = false;
14134             }
14135             mWindowManager.setForceResizableTasks(mForceResizableActivities);
14136             mWindowManager.setSupportsPictureInPicture(mSupportsPictureInPicture);
14137             // This happens before any activities are started, so we can change global configuration
14138             // in-place.
14139             updateConfigurationLocked(configuration, null, true);
14140             final Configuration globalConfig = getGlobalConfiguration();
14141             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Initial config: " + globalConfig);
14142
14143             // Load resources only after the current configuration has been set.
14144             final Resources res = mContext.getResources();
14145             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
14146             mThumbnailWidth = res.getDimensionPixelSize(
14147                     com.android.internal.R.dimen.thumbnail_width);
14148             mThumbnailHeight = res.getDimensionPixelSize(
14149                     com.android.internal.R.dimen.thumbnail_height);
14150             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
14151                     com.android.internal.R.string.config_appsNotReportingCrashes));
14152             mUserController.mUserSwitchUiEnabled = !res.getBoolean(
14153                     com.android.internal.R.bool.config_customUserSwitchUi);
14154             if ((globalConfig.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
14155                 mFullscreenThumbnailScale = (float) res
14156                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
14157                     (float) globalConfig.screenWidthDp;
14158             } else {
14159                 mFullscreenThumbnailScale = res.getFraction(
14160                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
14161             }
14162             mWaitForNetworkTimeoutMs = waitForNetworkTimeoutMs;
14163         }
14164     }
14165
14166     public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
14167         traceLog.traceBegin("PhaseActivityManagerReady");
14168         synchronized(this) {
14169             if (mSystemReady) {
14170                 // If we're done calling all the receivers, run the next "boot phase" passed in
14171                 // by the SystemServer
14172                 if (goingCallback != null) {
14173                     goingCallback.run();
14174                 }
14175                 return;
14176             }
14177
14178             mLocalDeviceIdleController
14179                     = LocalServices.getService(DeviceIdleController.LocalService.class);
14180             mAssistUtils = new AssistUtils(mContext);
14181             mVrController.onSystemReady();
14182             // Make sure we have the current profile info, since it is needed for security checks.
14183             mUserController.onSystemReady();
14184             mRecentTasks.onSystemReadyLocked();
14185             mAppOpsService.systemReady();
14186             mSystemReady = true;
14187         }
14188
14189         try {
14190             sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
14191                     ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
14192                     .getSerial();
14193         } catch (RemoteException e) {}
14194
14195         ArrayList<ProcessRecord> procsToKill = null;
14196         synchronized(mPidsSelfLocked) {
14197             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
14198                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
14199                 if (!isAllowedWhileBooting(proc.info)){
14200                     if (procsToKill == null) {
14201                         procsToKill = new ArrayList<ProcessRecord>();
14202                     }
14203                     procsToKill.add(proc);
14204                 }
14205             }
14206         }
14207
14208         synchronized(this) {
14209             if (procsToKill != null) {
14210                 for (int i=procsToKill.size()-1; i>=0; i--) {
14211                     ProcessRecord proc = procsToKill.get(i);
14212                     Slog.i(TAG, "Removing system update proc: " + proc);
14213                     removeProcessLocked(proc, true, false, "system update done");
14214                 }
14215             }
14216
14217             // Now that we have cleaned up any update processes, we
14218             // are ready to start launching real processes and know that
14219             // we won't trample on them any more.
14220             mProcessesReady = true;
14221         }
14222
14223         Slog.i(TAG, "System now ready");
14224         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
14225             SystemClock.uptimeMillis());
14226
14227         synchronized(this) {
14228             // Make sure we have no pre-ready processes sitting around.
14229
14230             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
14231                 ResolveInfo ri = mContext.getPackageManager()
14232                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
14233                                 STOCK_PM_FLAGS);
14234                 CharSequence errorMsg = null;
14235                 if (ri != null) {
14236                     ActivityInfo ai = ri.activityInfo;
14237                     ApplicationInfo app = ai.applicationInfo;
14238                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
14239                         mTopAction = Intent.ACTION_FACTORY_TEST;
14240                         mTopData = null;
14241                         mTopComponent = new ComponentName(app.packageName,
14242                                 ai.name);
14243                     } else {
14244                         errorMsg = mContext.getResources().getText(
14245                                 com.android.internal.R.string.factorytest_not_system);
14246                     }
14247                 } else {
14248                     errorMsg = mContext.getResources().getText(
14249                             com.android.internal.R.string.factorytest_no_action);
14250                 }
14251                 if (errorMsg != null) {
14252                     mTopAction = null;
14253                     mTopData = null;
14254                     mTopComponent = null;
14255                     Message msg = Message.obtain();
14256                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
14257                     msg.getData().putCharSequence("msg", errorMsg);
14258                     mUiHandler.sendMessage(msg);
14259                 }
14260             }
14261         }
14262
14263         retrieveSettings();
14264         final int currentUserId;
14265         synchronized (this) {
14266             currentUserId = mUserController.getCurrentUserIdLocked();
14267             readGrantedUriPermissionsLocked();
14268         }
14269
14270         if (goingCallback != null) goingCallback.run();
14271         traceLog.traceBegin("ActivityManagerStartApps");
14272         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
14273                 Integer.toString(currentUserId), currentUserId);
14274         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
14275                 Integer.toString(currentUserId), currentUserId);
14276         mSystemServiceManager.startUser(currentUserId);
14277
14278         synchronized (this) {
14279             // Only start up encryption-aware persistent apps; once user is
14280             // unlocked we'll come back around and start unaware apps
14281             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
14282
14283             // Start up initial activity.
14284             mBooting = true;
14285             // Enable home activity for system user, so that the system can always boot. We don't
14286             // do this when the system user is not setup since the setup wizard should be the one
14287             // to handle home activity in this case.
14288             if (UserManager.isSplitSystemUser() &&
14289                     Settings.Secure.getInt(mContext.getContentResolver(),
14290                          Settings.Secure.USER_SETUP_COMPLETE, 0) != 0) {
14291                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
14292                 try {
14293                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
14294                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
14295                             UserHandle.USER_SYSTEM);
14296                 } catch (RemoteException e) {
14297                     throw e.rethrowAsRuntimeException();
14298                 }
14299             }
14300             startHomeActivityLocked(currentUserId, "systemReady");
14301
14302             try {
14303                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
14304                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
14305                             + " data partition or your device will be unstable.");
14306                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
14307                 }
14308             } catch (RemoteException e) {
14309             }
14310
14311             if (!Build.isBuildConsistent()) {
14312                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
14313                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
14314             }
14315
14316             long ident = Binder.clearCallingIdentity();
14317             try {
14318                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14319                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14320                         | Intent.FLAG_RECEIVER_FOREGROUND);
14321                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14322                 broadcastIntentLocked(null, null, intent,
14323                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14324                         null, false, false, MY_PID, SYSTEM_UID,
14325                         currentUserId);
14326                 intent = new Intent(Intent.ACTION_USER_STARTING);
14327                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14328                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
14329                 broadcastIntentLocked(null, null, intent,
14330                         null, new IIntentReceiver.Stub() {
14331                             @Override
14332                             public void performReceive(Intent intent, int resultCode, String data,
14333                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14334                                     throws RemoteException {
14335                             }
14336                         }, 0, null, null,
14337                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
14338                         null, true, false, MY_PID, SYSTEM_UID, UserHandle.USER_ALL);
14339             } catch (Throwable t) {
14340                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
14341             } finally {
14342                 Binder.restoreCallingIdentity(ident);
14343             }
14344             mStackSupervisor.resumeFocusedStackTopActivityLocked();
14345             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
14346             traceLog.traceEnd(); // ActivityManagerStartApps
14347             traceLog.traceEnd(); // PhaseActivityManagerReady
14348         }
14349     }
14350
14351     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
14352         synchronized (this) {
14353             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
14354         }
14355     }
14356
14357     void skipCurrentReceiverLocked(ProcessRecord app) {
14358         for (BroadcastQueue queue : mBroadcastQueues) {
14359             queue.skipCurrentReceiverLocked(app);
14360         }
14361     }
14362
14363     /**
14364      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
14365      * The application process will exit immediately after this call returns.
14366      * @param app object of the crashing app, null for the system server
14367      * @param crashInfo describing the exception
14368      */
14369     public void handleApplicationCrash(IBinder app,
14370             ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14371         ProcessRecord r = findAppProcess(app, "Crash");
14372         final String processName = app == null ? "system_server"
14373                 : (r == null ? "unknown" : r.processName);
14374
14375         handleApplicationCrashInner("crash", r, processName, crashInfo);
14376     }
14377
14378     /* Native crash reporting uses this inner version because it needs to be somewhat
14379      * decoupled from the AM-managed cleanup lifecycle
14380      */
14381     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
14382             ApplicationErrorReport.CrashInfo crashInfo) {
14383         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
14384                 UserHandle.getUserId(Binder.getCallingUid()), processName,
14385                 r == null ? -1 : r.info.flags,
14386                 crashInfo.exceptionClassName,
14387                 crashInfo.exceptionMessage,
14388                 crashInfo.throwFileName,
14389                 crashInfo.throwLineNumber);
14390
14391         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
14392
14393         mAppErrors.crashApplication(r, crashInfo);
14394     }
14395
14396     public void handleApplicationStrictModeViolation(
14397             IBinder app,
14398             int violationMask,
14399             StrictMode.ViolationInfo info) {
14400         ProcessRecord r = findAppProcess(app, "StrictMode");
14401         if (r == null) {
14402             return;
14403         }
14404
14405         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
14406             Integer stackFingerprint = info.hashCode();
14407             boolean logIt = true;
14408             synchronized (mAlreadyLoggedViolatedStacks) {
14409                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
14410                     logIt = false;
14411                     // TODO: sub-sample into EventLog for these, with
14412                     // the info.durationMillis?  Then we'd get
14413                     // the relative pain numbers, without logging all
14414                     // the stack traces repeatedly.  We'd want to do
14415                     // likewise in the client code, which also does
14416                     // dup suppression, before the Binder call.
14417                 } else {
14418                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
14419                         mAlreadyLoggedViolatedStacks.clear();
14420                     }
14421                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
14422                 }
14423             }
14424             if (logIt) {
14425                 logStrictModeViolationToDropBox(r, info);
14426             }
14427         }
14428
14429         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
14430             AppErrorResult result = new AppErrorResult();
14431             synchronized (this) {
14432                 final long origId = Binder.clearCallingIdentity();
14433
14434                 Message msg = Message.obtain();
14435                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
14436                 HashMap<String, Object> data = new HashMap<String, Object>();
14437                 data.put("result", result);
14438                 data.put("app", r);
14439                 data.put("violationMask", violationMask);
14440                 data.put("info", info);
14441                 msg.obj = data;
14442                 mUiHandler.sendMessage(msg);
14443
14444                 Binder.restoreCallingIdentity(origId);
14445             }
14446             int res = result.get();
14447             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
14448         }
14449     }
14450
14451     // Depending on the policy in effect, there could be a bunch of
14452     // these in quick succession so we try to batch these together to
14453     // minimize disk writes, number of dropbox entries, and maximize
14454     // compression, by having more fewer, larger records.
14455     private void logStrictModeViolationToDropBox(
14456             ProcessRecord process,
14457             StrictMode.ViolationInfo info) {
14458         if (info == null) {
14459             return;
14460         }
14461         final boolean isSystemApp = process == null ||
14462                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
14463                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
14464         final String processName = process == null ? "unknown" : process.processName;
14465         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
14466         final DropBoxManager dbox = (DropBoxManager)
14467                 mContext.getSystemService(Context.DROPBOX_SERVICE);
14468
14469         // Exit early if the dropbox isn't configured to accept this report type.
14470         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14471
14472         boolean bufferWasEmpty;
14473         boolean needsFlush;
14474         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
14475         synchronized (sb) {
14476             bufferWasEmpty = sb.length() == 0;
14477             appendDropBoxProcessHeaders(process, processName, sb);
14478             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14479             sb.append("System-App: ").append(isSystemApp).append("\n");
14480             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
14481             if (info.violationNumThisLoop != 0) {
14482                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
14483             }
14484             if (info.numAnimationsRunning != 0) {
14485                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
14486             }
14487             if (info.broadcastIntentAction != null) {
14488                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
14489             }
14490             if (info.durationMillis != -1) {
14491                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
14492             }
14493             if (info.numInstances != -1) {
14494                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
14495             }
14496             if (info.tags != null) {
14497                 for (String tag : info.tags) {
14498                     sb.append("Span-Tag: ").append(tag).append("\n");
14499                 }
14500             }
14501             sb.append("\n");
14502             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
14503                 sb.append(info.crashInfo.stackTrace);
14504                 sb.append("\n");
14505             }
14506             if (info.message != null) {
14507                 sb.append(info.message);
14508                 sb.append("\n");
14509             }
14510
14511             // Only buffer up to ~64k.  Various logging bits truncate
14512             // things at 128k.
14513             needsFlush = (sb.length() > 64 * 1024);
14514         }
14515
14516         // Flush immediately if the buffer's grown too large, or this
14517         // is a non-system app.  Non-system apps are isolated with a
14518         // different tag & policy and not batched.
14519         //
14520         // Batching is useful during internal testing with
14521         // StrictMode settings turned up high.  Without batching,
14522         // thousands of separate files could be created on boot.
14523         if (!isSystemApp || needsFlush) {
14524             new Thread("Error dump: " + dropboxTag) {
14525                 @Override
14526                 public void run() {
14527                     String report;
14528                     synchronized (sb) {
14529                         report = sb.toString();
14530                         sb.delete(0, sb.length());
14531                         sb.trimToSize();
14532                     }
14533                     if (report.length() != 0) {
14534                         dbox.addText(dropboxTag, report);
14535                     }
14536                 }
14537             }.start();
14538             return;
14539         }
14540
14541         // System app batching:
14542         if (!bufferWasEmpty) {
14543             // An existing dropbox-writing thread is outstanding, so
14544             // we don't need to start it up.  The existing thread will
14545             // catch the buffer appends we just did.
14546             return;
14547         }
14548
14549         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
14550         // (After this point, we shouldn't access AMS internal data structures.)
14551         new Thread("Error dump: " + dropboxTag) {
14552             @Override
14553             public void run() {
14554                 // 5 second sleep to let stacks arrive and be batched together
14555                 try {
14556                     Thread.sleep(5000);  // 5 seconds
14557                 } catch (InterruptedException e) {}
14558
14559                 String errorReport;
14560                 synchronized (mStrictModeBuffer) {
14561                     errorReport = mStrictModeBuffer.toString();
14562                     if (errorReport.length() == 0) {
14563                         return;
14564                     }
14565                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
14566                     mStrictModeBuffer.trimToSize();
14567                 }
14568                 dbox.addText(dropboxTag, errorReport);
14569             }
14570         }.start();
14571     }
14572
14573     /**
14574      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
14575      * @param app object of the crashing app, null for the system server
14576      * @param tag reported by the caller
14577      * @param system whether this wtf is coming from the system
14578      * @param crashInfo describing the context of the error
14579      * @return true if the process should exit immediately (WTF is fatal)
14580      */
14581     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
14582             final ApplicationErrorReport.ParcelableCrashInfo crashInfo) {
14583         final int callingUid = Binder.getCallingUid();
14584         final int callingPid = Binder.getCallingPid();
14585
14586         if (system) {
14587             // If this is coming from the system, we could very well have low-level
14588             // system locks held, so we want to do this all asynchronously.  And we
14589             // never want this to become fatal, so there is that too.
14590             mHandler.post(new Runnable() {
14591                 @Override public void run() {
14592                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
14593                 }
14594             });
14595             return false;
14596         }
14597
14598         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
14599                 crashInfo);
14600
14601         final boolean isFatal = Build.IS_ENG || Settings.Global
14602                 .getInt(mContext.getContentResolver(), Settings.Global.WTF_IS_FATAL, 0) != 0;
14603         final boolean isSystem = (r == null) || r.persistent;
14604
14605         if (isFatal && !isSystem) {
14606             mAppErrors.crashApplication(r, crashInfo);
14607             return true;
14608         } else {
14609             return false;
14610         }
14611     }
14612
14613     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
14614             final ApplicationErrorReport.CrashInfo crashInfo) {
14615         final ProcessRecord r = findAppProcess(app, "WTF");
14616         final String processName = app == null ? "system_server"
14617                 : (r == null ? "unknown" : r.processName);
14618
14619         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
14620                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
14621
14622         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
14623
14624         return r;
14625     }
14626
14627     /**
14628      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
14629      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
14630      */
14631     private ProcessRecord findAppProcess(IBinder app, String reason) {
14632         if (app == null) {
14633             return null;
14634         }
14635
14636         synchronized (this) {
14637             final int NP = mProcessNames.getMap().size();
14638             for (int ip=0; ip<NP; ip++) {
14639                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
14640                 final int NA = apps.size();
14641                 for (int ia=0; ia<NA; ia++) {
14642                     ProcessRecord p = apps.valueAt(ia);
14643                     if (p.thread != null && p.thread.asBinder() == app) {
14644                         return p;
14645                     }
14646                 }
14647             }
14648
14649             Slog.w(TAG, "Can't find mystery application for " + reason
14650                     + " from pid=" + Binder.getCallingPid()
14651                     + " uid=" + Binder.getCallingUid() + ": " + app);
14652             return null;
14653         }
14654     }
14655
14656     /**
14657      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
14658      * to append various headers to the dropbox log text.
14659      */
14660     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
14661             StringBuilder sb) {
14662         // Watchdog thread ends up invoking this function (with
14663         // a null ProcessRecord) to add the stack file to dropbox.
14664         // Do not acquire a lock on this (am) in such cases, as it
14665         // could cause a potential deadlock, if and when watchdog
14666         // is invoked due to unavailability of lock on am and it
14667         // would prevent watchdog from killing system_server.
14668         if (process == null) {
14669             sb.append("Process: ").append(processName).append("\n");
14670             return;
14671         }
14672         // Note: ProcessRecord 'process' is guarded by the service
14673         // instance.  (notably process.pkgList, which could otherwise change
14674         // concurrently during execution of this method)
14675         synchronized (this) {
14676             sb.append("Process: ").append(processName).append("\n");
14677             sb.append("PID: ").append(process.pid).append("\n");
14678             int flags = process.info.flags;
14679             IPackageManager pm = AppGlobals.getPackageManager();
14680             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
14681             for (int ip=0; ip<process.pkgList.size(); ip++) {
14682                 String pkg = process.pkgList.keyAt(ip);
14683                 sb.append("Package: ").append(pkg);
14684                 try {
14685                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
14686                     if (pi != null) {
14687                         sb.append(" v").append(pi.versionCode);
14688                         if (pi.versionName != null) {
14689                             sb.append(" (").append(pi.versionName).append(")");
14690                         }
14691                     }
14692                 } catch (RemoteException e) {
14693                     Slog.e(TAG, "Error getting package info: " + pkg, e);
14694                 }
14695                 sb.append("\n");
14696             }
14697             if (process.info.isInstantApp()) {
14698                 sb.append("Instant-App: true\n");
14699             }
14700         }
14701     }
14702
14703     private static String processClass(ProcessRecord process) {
14704         if (process == null || process.pid == MY_PID) {
14705             return "system_server";
14706         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14707             return "system_app";
14708         } else {
14709             return "data_app";
14710         }
14711     }
14712
14713     private volatile long mWtfClusterStart;
14714     private volatile int mWtfClusterCount;
14715
14716     /**
14717      * Write a description of an error (crash, WTF, ANR) to the drop box.
14718      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
14719      * @param process which caused the error, null means the system server
14720      * @param activity which triggered the error, null if unknown
14721      * @param parent activity related to the error, null if unknown
14722      * @param subject line related to the error, null if absent
14723      * @param report in long form describing the error, null if absent
14724      * @param dataFile text file to include in the report, null if none
14725      * @param crashInfo giving an application stack trace, null if absent
14726      */
14727     public void addErrorToDropBox(String eventType,
14728             ProcessRecord process, String processName, ActivityRecord activity,
14729             ActivityRecord parent, String subject,
14730             final String report, final File dataFile,
14731             final ApplicationErrorReport.CrashInfo crashInfo) {
14732         // NOTE -- this must never acquire the ActivityManagerService lock,
14733         // otherwise the watchdog may be prevented from resetting the system.
14734
14735         // Bail early if not published yet
14736         if (ServiceManager.getService(Context.DROPBOX_SERVICE) == null) return;
14737         final DropBoxManager dbox = mContext.getSystemService(DropBoxManager.class);
14738
14739         // Exit early if the dropbox isn't configured to accept this report type.
14740         final String dropboxTag = processClass(process) + "_" + eventType;
14741         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
14742
14743         // Rate-limit how often we're willing to do the heavy lifting below to
14744         // collect and record logs; currently 5 logs per 10 second period.
14745         final long now = SystemClock.elapsedRealtime();
14746         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
14747             mWtfClusterStart = now;
14748             mWtfClusterCount = 1;
14749         } else {
14750             if (mWtfClusterCount++ >= 5) return;
14751         }
14752
14753         final StringBuilder sb = new StringBuilder(1024);
14754         appendDropBoxProcessHeaders(process, processName, sb);
14755         if (process != null) {
14756             sb.append("Foreground: ")
14757                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
14758                     .append("\n");
14759         }
14760         if (activity != null) {
14761             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
14762         }
14763         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
14764             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
14765         }
14766         if (parent != null && parent != activity) {
14767             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
14768         }
14769         if (subject != null) {
14770             sb.append("Subject: ").append(subject).append("\n");
14771         }
14772         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
14773         if (Debug.isDebuggerConnected()) {
14774             sb.append("Debugger: Connected\n");
14775         }
14776         sb.append("\n");
14777
14778         // Do the rest in a worker thread to avoid blocking the caller on I/O
14779         // (After this point, we shouldn't access AMS internal data structures.)
14780         Thread worker = new Thread("Error dump: " + dropboxTag) {
14781             @Override
14782             public void run() {
14783                 if (report != null) {
14784                     sb.append(report);
14785                 }
14786
14787                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
14788                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
14789                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
14790                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
14791
14792                 if (dataFile != null && maxDataFileSize > 0) {
14793                     try {
14794                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
14795                                     "\n\n[[TRUNCATED]]"));
14796                     } catch (IOException e) {
14797                         Slog.e(TAG, "Error reading " + dataFile, e);
14798                     }
14799                 }
14800                 if (crashInfo != null && crashInfo.stackTrace != null) {
14801                     sb.append(crashInfo.stackTrace);
14802                 }
14803
14804                 if (lines > 0) {
14805                     sb.append("\n");
14806
14807                     // Merge several logcat streams, and take the last N lines
14808                     InputStreamReader input = null;
14809                     try {
14810                         java.lang.Process logcat = new ProcessBuilder(
14811                                 "/system/bin/timeout", "-k", "15s", "10s",
14812                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
14813                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
14814                                         .redirectErrorStream(true).start();
14815
14816                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
14817                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
14818                         input = new InputStreamReader(logcat.getInputStream());
14819
14820                         int num;
14821                         char[] buf = new char[8192];
14822                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
14823                     } catch (IOException e) {
14824                         Slog.e(TAG, "Error running logcat", e);
14825                     } finally {
14826                         if (input != null) try { input.close(); } catch (IOException e) {}
14827                     }
14828                 }
14829
14830                 dbox.addText(dropboxTag, sb.toString());
14831             }
14832         };
14833
14834         if (process == null) {
14835             // If process is null, we are being called from some internal code
14836             // and may be about to die -- run this synchronously.
14837             worker.run();
14838         } else {
14839             worker.start();
14840         }
14841     }
14842
14843     @Override
14844     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
14845         enforceNotIsolatedCaller("getProcessesInErrorState");
14846         // assume our apps are happy - lazy create the list
14847         List<ActivityManager.ProcessErrorStateInfo> errList = null;
14848
14849         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14850                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
14851         int userId = UserHandle.getUserId(Binder.getCallingUid());
14852
14853         synchronized (this) {
14854
14855             // iterate across all processes
14856             for (int i=mLruProcesses.size()-1; i>=0; i--) {
14857                 ProcessRecord app = mLruProcesses.get(i);
14858                 if (!allUsers && app.userId != userId) {
14859                     continue;
14860                 }
14861                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
14862                     // This one's in trouble, so we'll generate a report for it
14863                     // crashes are higher priority (in case there's a crash *and* an anr)
14864                     ActivityManager.ProcessErrorStateInfo report = null;
14865                     if (app.crashing) {
14866                         report = app.crashingReport;
14867                     } else if (app.notResponding) {
14868                         report = app.notRespondingReport;
14869                     }
14870
14871                     if (report != null) {
14872                         if (errList == null) {
14873                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
14874                         }
14875                         errList.add(report);
14876                     } else {
14877                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
14878                                 " crashing = " + app.crashing +
14879                                 " notResponding = " + app.notResponding);
14880                     }
14881                 }
14882             }
14883         }
14884
14885         return errList;
14886     }
14887
14888     static int procStateToImportance(int procState, int memAdj,
14889             ActivityManager.RunningAppProcessInfo currApp,
14890             int clientTargetSdk) {
14891         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk(
14892                 procState, clientTargetSdk);
14893         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14894             currApp.lru = memAdj;
14895         } else {
14896             currApp.lru = 0;
14897         }
14898         return imp;
14899     }
14900
14901     private void fillInProcMemInfo(ProcessRecord app,
14902             ActivityManager.RunningAppProcessInfo outInfo,
14903             int clientTargetSdk) {
14904         outInfo.pid = app.pid;
14905         outInfo.uid = app.info.uid;
14906         if (mHeavyWeightProcess == app) {
14907             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14908         }
14909         if (app.persistent) {
14910             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14911         }
14912         if (app.activities.size() > 0) {
14913             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14914         }
14915         outInfo.lastTrimLevel = app.trimMemoryLevel;
14916         int adj = app.curAdj;
14917         int procState = app.curProcState;
14918         outInfo.importance = procStateToImportance(procState, adj, outInfo, clientTargetSdk);
14919         outInfo.importanceReasonCode = app.adjTypeCode;
14920         outInfo.processState = app.curProcState;
14921     }
14922
14923     @Override
14924     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14925         enforceNotIsolatedCaller("getRunningAppProcesses");
14926
14927         final int callingUid = Binder.getCallingUid();
14928         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
14929
14930         // Lazy instantiation of list
14931         List<ActivityManager.RunningAppProcessInfo> runList = null;
14932         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14933                 callingUid) == PackageManager.PERMISSION_GRANTED;
14934         final int userId = UserHandle.getUserId(callingUid);
14935         final boolean allUids = isGetTasksAllowed(
14936                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14937
14938         synchronized (this) {
14939             // Iterate across all processes
14940             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14941                 ProcessRecord app = mLruProcesses.get(i);
14942                 if ((!allUsers && app.userId != userId)
14943                         || (!allUids && app.uid != callingUid)) {
14944                     continue;
14945                 }
14946                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14947                     // Generate process state info for running application
14948                     ActivityManager.RunningAppProcessInfo currApp =
14949                         new ActivityManager.RunningAppProcessInfo(app.processName,
14950                                 app.pid, app.getPackageList());
14951                     fillInProcMemInfo(app, currApp, clientTargetSdk);
14952                     if (app.adjSource instanceof ProcessRecord) {
14953                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14954                         currApp.importanceReasonImportance =
14955                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14956                                         app.adjSourceProcState);
14957                     } else if (app.adjSource instanceof ActivityRecord) {
14958                         ActivityRecord r = (ActivityRecord)app.adjSource;
14959                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14960                     }
14961                     if (app.adjTarget instanceof ComponentName) {
14962                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14963                     }
14964                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14965                     //        + " lru=" + currApp.lru);
14966                     if (runList == null) {
14967                         runList = new ArrayList<>();
14968                     }
14969                     runList.add(currApp);
14970                 }
14971             }
14972         }
14973         return runList;
14974     }
14975
14976     @Override
14977     public List<ApplicationInfo> getRunningExternalApplications() {
14978         enforceNotIsolatedCaller("getRunningExternalApplications");
14979         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14980         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14981         if (runningApps != null && runningApps.size() > 0) {
14982             Set<String> extList = new HashSet<String>();
14983             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14984                 if (app.pkgList != null) {
14985                     for (String pkg : app.pkgList) {
14986                         extList.add(pkg);
14987                     }
14988                 }
14989             }
14990             IPackageManager pm = AppGlobals.getPackageManager();
14991             for (String pkg : extList) {
14992                 try {
14993                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14994                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14995                         retList.add(info);
14996                     }
14997                 } catch (RemoteException e) {
14998                 }
14999             }
15000         }
15001         return retList;
15002     }
15003
15004     @Override
15005     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
15006         enforceNotIsolatedCaller("getMyMemoryState");
15007
15008         final int callingUid = Binder.getCallingUid();
15009         final int clientTargetSdk = mPackageManagerInt.getUidTargetSdkVersion(callingUid);
15010
15011         synchronized (this) {
15012             ProcessRecord proc;
15013             synchronized (mPidsSelfLocked) {
15014                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
15015             }
15016             fillInProcMemInfo(proc, outInfo, clientTargetSdk);
15017         }
15018     }
15019
15020     @Override
15021     public int getMemoryTrimLevel() {
15022         enforceNotIsolatedCaller("getMyMemoryState");
15023         synchronized (this) {
15024             return mLastMemoryLevel;
15025         }
15026     }
15027
15028     @Override
15029     public void onShellCommand(FileDescriptor in, FileDescriptor out,
15030             FileDescriptor err, String[] args, ShellCallback callback,
15031             ResultReceiver resultReceiver) {
15032         (new ActivityManagerShellCommand(this, false)).exec(
15033                 this, in, out, err, args, callback, resultReceiver);
15034     }
15035
15036     SleepToken acquireSleepToken(String tag, int displayId) {
15037         synchronized (this) {
15038             final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
15039             updateSleepIfNeededLocked();
15040             return token;
15041         }
15042     }
15043
15044     @Override
15045     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
15046         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
15047
15048         boolean dumpAll = false;
15049         boolean dumpClient = false;
15050         boolean dumpCheckin = false;
15051         boolean dumpCheckinFormat = false;
15052         boolean dumpVisibleStacksOnly = false;
15053         boolean dumpFocusedStackOnly = false;
15054         String dumpPackage = null;
15055
15056         int opti = 0;
15057         while (opti < args.length) {
15058             String opt = args[opti];
15059             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15060                 break;
15061             }
15062             opti++;
15063             if ("-a".equals(opt)) {
15064                 dumpAll = true;
15065             } else if ("-c".equals(opt)) {
15066                 dumpClient = true;
15067             } else if ("-v".equals(opt)) {
15068                 dumpVisibleStacksOnly = true;
15069             } else if ("-f".equals(opt)) {
15070                 dumpFocusedStackOnly = true;
15071             } else if ("-p".equals(opt)) {
15072                 if (opti < args.length) {
15073                     dumpPackage = args[opti];
15074                     opti++;
15075                 } else {
15076                     pw.println("Error: -p option requires package argument");
15077                     return;
15078                 }
15079                 dumpClient = true;
15080             } else if ("--checkin".equals(opt)) {
15081                 dumpCheckin = dumpCheckinFormat = true;
15082             } else if ("-C".equals(opt)) {
15083                 dumpCheckinFormat = true;
15084             } else if ("-h".equals(opt)) {
15085                 ActivityManagerShellCommand.dumpHelp(pw, true);
15086                 return;
15087             } else {
15088                 pw.println("Unknown argument: " + opt + "; use -h for help");
15089             }
15090         }
15091
15092         long origId = Binder.clearCallingIdentity();
15093         boolean more = false;
15094         // Is the caller requesting to dump a particular piece of data?
15095         if (opti < args.length) {
15096             String cmd = args[opti];
15097             opti++;
15098             if ("activities".equals(cmd) || "a".equals(cmd)) {
15099                 synchronized (this) {
15100                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15101                 }
15102             } else if ("lastanr".equals(cmd)) {
15103                 synchronized (this) {
15104                     dumpLastANRLocked(pw);
15105                 }
15106             } else if ("starter".equals(cmd)) {
15107                 synchronized (this) {
15108                     dumpActivityStarterLocked(pw, dumpPackage);
15109                 }
15110             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
15111                 synchronized (this) {
15112                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
15113                 }
15114             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
15115                 String[] newArgs;
15116                 String name;
15117                 if (opti >= args.length) {
15118                     name = null;
15119                     newArgs = EMPTY_STRING_ARRAY;
15120                 } else {
15121                     dumpPackage = args[opti];
15122                     opti++;
15123                     newArgs = new String[args.length - opti];
15124                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15125                             args.length - opti);
15126                 }
15127                 synchronized (this) {
15128                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
15129                 }
15130             } else if ("broadcast-stats".equals(cmd)) {
15131                 String[] newArgs;
15132                 String name;
15133                 if (opti >= args.length) {
15134                     name = null;
15135                     newArgs = EMPTY_STRING_ARRAY;
15136                 } else {
15137                     dumpPackage = args[opti];
15138                     opti++;
15139                     newArgs = new String[args.length - opti];
15140                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15141                             args.length - opti);
15142                 }
15143                 synchronized (this) {
15144                     if (dumpCheckinFormat) {
15145                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
15146                                 dumpPackage);
15147                     } else {
15148                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
15149                     }
15150                 }
15151             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
15152                 String[] newArgs;
15153                 String name;
15154                 if (opti >= args.length) {
15155                     name = null;
15156                     newArgs = EMPTY_STRING_ARRAY;
15157                 } else {
15158                     dumpPackage = args[opti];
15159                     opti++;
15160                     newArgs = new String[args.length - opti];
15161                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15162                             args.length - opti);
15163                 }
15164                 synchronized (this) {
15165                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
15166                 }
15167             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
15168                 String[] newArgs;
15169                 String name;
15170                 if (opti >= args.length) {
15171                     name = null;
15172                     newArgs = EMPTY_STRING_ARRAY;
15173                 } else {
15174                     dumpPackage = args[opti];
15175                     opti++;
15176                     newArgs = new String[args.length - opti];
15177                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15178                             args.length - opti);
15179                 }
15180                 synchronized (this) {
15181                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
15182                 }
15183             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
15184                 synchronized (this) {
15185                     dumpOomLocked(fd, pw, args, opti, true);
15186                 }
15187             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
15188                 synchronized (this) {
15189                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
15190                 }
15191             } else if ("provider".equals(cmd)) {
15192                 String[] newArgs;
15193                 String name;
15194                 if (opti >= args.length) {
15195                     name = null;
15196                     newArgs = EMPTY_STRING_ARRAY;
15197                 } else {
15198                     name = args[opti];
15199                     opti++;
15200                     newArgs = new String[args.length - opti];
15201                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15202                 }
15203                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
15204                     pw.println("No providers match: " + name);
15205                     pw.println("Use -h for help.");
15206                 }
15207             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
15208                 synchronized (this) {
15209                     dumpProvidersLocked(fd, pw, args, opti, true, null);
15210                 }
15211             } else if ("service".equals(cmd)) {
15212                 String[] newArgs;
15213                 String name;
15214                 if (opti >= args.length) {
15215                     name = null;
15216                     newArgs = EMPTY_STRING_ARRAY;
15217                 } else {
15218                     name = args[opti];
15219                     opti++;
15220                     newArgs = new String[args.length - opti];
15221                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15222                             args.length - opti);
15223                 }
15224                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
15225                     pw.println("No services match: " + name);
15226                     pw.println("Use -h for help.");
15227                 }
15228             } else if ("package".equals(cmd)) {
15229                 String[] newArgs;
15230                 if (opti >= args.length) {
15231                     pw.println("package: no package name specified");
15232                     pw.println("Use -h for help.");
15233                 } else {
15234                     dumpPackage = args[opti];
15235                     opti++;
15236                     newArgs = new String[args.length - opti];
15237                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
15238                             args.length - opti);
15239                     args = newArgs;
15240                     opti = 0;
15241                     more = true;
15242                 }
15243             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
15244                 synchronized (this) {
15245                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
15246                 }
15247             } else if ("settings".equals(cmd)) {
15248                 synchronized (this) {
15249                     mConstants.dump(pw);
15250                 }
15251             } else if ("services".equals(cmd) || "s".equals(cmd)) {
15252                 if (dumpClient) {
15253                     ActiveServices.ServiceDumper dumper;
15254                     synchronized (this) {
15255                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15256                                 dumpPackage);
15257                     }
15258                     dumper.dumpWithClient();
15259                 } else {
15260                     synchronized (this) {
15261                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
15262                                 dumpPackage).dumpLocked();
15263                     }
15264                 }
15265             } else if ("locks".equals(cmd)) {
15266                 LockGuard.dump(fd, pw, args);
15267             } else {
15268                 // Dumping a single activity?
15269                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll, dumpVisibleStacksOnly,
15270                         dumpFocusedStackOnly)) {
15271                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
15272                     int res = shell.exec(this, null, fd, null, args, null,
15273                             new ResultReceiver(null));
15274                     if (res < 0) {
15275                         pw.println("Bad activity command, or no activities match: " + cmd);
15276                         pw.println("Use -h for help.");
15277                     }
15278                 }
15279             }
15280             if (!more) {
15281                 Binder.restoreCallingIdentity(origId);
15282                 return;
15283             }
15284         }
15285
15286         // No piece of data specified, dump everything.
15287         if (dumpCheckinFormat) {
15288             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
15289         } else if (dumpClient) {
15290             ActiveServices.ServiceDumper sdumper;
15291             synchronized (this) {
15292                 mConstants.dump(pw);
15293                 pw.println();
15294                 if (dumpAll) {
15295                     pw.println("-------------------------------------------------------------------------------");
15296                 }
15297                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15298                 pw.println();
15299                 if (dumpAll) {
15300                     pw.println("-------------------------------------------------------------------------------");
15301                 }
15302                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15303                 pw.println();
15304                 if (dumpAll) {
15305                     pw.println("-------------------------------------------------------------------------------");
15306                 }
15307                 if (dumpAll || dumpPackage != null) {
15308                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15309                     pw.println();
15310                     if (dumpAll) {
15311                         pw.println("-------------------------------------------------------------------------------");
15312                     }
15313                 }
15314                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15315                 pw.println();
15316                 if (dumpAll) {
15317                     pw.println("-------------------------------------------------------------------------------");
15318                 }
15319                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15320                 pw.println();
15321                 if (dumpAll) {
15322                     pw.println("-------------------------------------------------------------------------------");
15323                 }
15324                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
15325                         dumpPackage);
15326             }
15327             sdumper.dumpWithClient();
15328             pw.println();
15329             synchronized (this) {
15330                 if (dumpAll) {
15331                     pw.println("-------------------------------------------------------------------------------");
15332                 }
15333                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15334                 pw.println();
15335                 if (dumpAll) {
15336                     pw.println("-------------------------------------------------------------------------------");
15337                 }
15338                 dumpLastANRLocked(pw);
15339                 pw.println();
15340                 if (dumpAll) {
15341                     pw.println("-------------------------------------------------------------------------------");
15342                 }
15343                 dumpActivityStarterLocked(pw, dumpPackage);
15344                 pw.println();
15345                 if (dumpAll) {
15346                     pw.println("-------------------------------------------------------------------------------");
15347                 }
15348                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15349                 if (mAssociations.size() > 0) {
15350                     pw.println();
15351                     if (dumpAll) {
15352                         pw.println("-------------------------------------------------------------------------------");
15353                     }
15354                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15355                 }
15356                 pw.println();
15357                 if (dumpAll) {
15358                     pw.println("-------------------------------------------------------------------------------");
15359                 }
15360                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15361             }
15362
15363         } else {
15364             synchronized (this) {
15365                 mConstants.dump(pw);
15366                 pw.println();
15367                 if (dumpAll) {
15368                     pw.println("-------------------------------------------------------------------------------");
15369                 }
15370                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15371                 pw.println();
15372                 if (dumpAll) {
15373                     pw.println("-------------------------------------------------------------------------------");
15374                 }
15375                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15376                 pw.println();
15377                 if (dumpAll) {
15378                     pw.println("-------------------------------------------------------------------------------");
15379                 }
15380                 if (dumpAll || dumpPackage != null) {
15381                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15382                     pw.println();
15383                     if (dumpAll) {
15384                         pw.println("-------------------------------------------------------------------------------");
15385                     }
15386                 }
15387                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15388                 pw.println();
15389                 if (dumpAll) {
15390                     pw.println("-------------------------------------------------------------------------------");
15391                 }
15392                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15393                 pw.println();
15394                 if (dumpAll) {
15395                     pw.println("-------------------------------------------------------------------------------");
15396                 }
15397                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
15398                         .dumpLocked();
15399                 pw.println();
15400                 if (dumpAll) {
15401                     pw.println("-------------------------------------------------------------------------------");
15402                 }
15403                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15404                 pw.println();
15405                 if (dumpAll) {
15406                     pw.println("-------------------------------------------------------------------------------");
15407                 }
15408                 dumpLastANRLocked(pw);
15409                 pw.println();
15410                 if (dumpAll) {
15411                     pw.println("-------------------------------------------------------------------------------");
15412                 }
15413                 dumpActivityStarterLocked(pw, dumpPackage);
15414                 pw.println();
15415                 if (dumpAll) {
15416                     pw.println("-------------------------------------------------------------------------------");
15417                 }
15418                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15419                 if (mAssociations.size() > 0) {
15420                     pw.println();
15421                     if (dumpAll) {
15422                         pw.println("-------------------------------------------------------------------------------");
15423                     }
15424                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
15425                 }
15426                 pw.println();
15427                 if (dumpAll) {
15428                     pw.println("-------------------------------------------------------------------------------");
15429                 }
15430                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
15431             }
15432         }
15433         Binder.restoreCallingIdentity(origId);
15434     }
15435
15436     private void dumpLastANRLocked(PrintWriter pw) {
15437         pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
15438         if (mLastANRState == null) {
15439             pw.println("  <no ANR has occurred since boot>");
15440         } else {
15441             pw.println(mLastANRState);
15442         }
15443     }
15444
15445     private void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
15446         pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
15447         mActivityStarter.dump(pw, "", dumpPackage);
15448     }
15449
15450     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15451             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15452         dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
15453                 "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
15454     }
15455
15456     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15457             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
15458         pw.println(header);
15459
15460         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
15461                 dumpPackage);
15462         boolean needSep = printedAnything;
15463
15464         boolean printed = ActivityStackSupervisor.printThisActivity(pw,
15465                 mStackSupervisor.getResumedActivityLocked(),
15466                 dumpPackage, needSep, "  ResumedActivity: ");
15467         if (printed) {
15468             printedAnything = true;
15469             needSep = false;
15470         }
15471
15472         if (dumpPackage == null) {
15473             if (needSep) {
15474                 pw.println();
15475             }
15476             printedAnything = true;
15477             mStackSupervisor.dump(pw, "  ");
15478         }
15479
15480         if (!printedAnything) {
15481             pw.println("  (nothing)");
15482         }
15483     }
15484
15485     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15486             int opti, boolean dumpAll, String dumpPackage) {
15487         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
15488
15489         boolean printedAnything = false;
15490
15491         if (mRecentTasks != null && mRecentTasks.size() > 0) {
15492             boolean printedHeader = false;
15493
15494             final int N = mRecentTasks.size();
15495             for (int i=0; i<N; i++) {
15496                 TaskRecord tr = mRecentTasks.get(i);
15497                 if (dumpPackage != null) {
15498                     if (tr.realActivity == null ||
15499                             !dumpPackage.equals(tr.realActivity.getPackageName())) {
15500                         continue;
15501                     }
15502                 }
15503                 if (!printedHeader) {
15504                     pw.println("  Recent tasks:");
15505                     printedHeader = true;
15506                     printedAnything = true;
15507                 }
15508                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
15509                         pw.println(tr);
15510                 if (dumpAll) {
15511                     mRecentTasks.get(i).dump(pw, "    ");
15512                 }
15513             }
15514         }
15515
15516         if (!printedAnything) {
15517             pw.println("  (nothing)");
15518         }
15519     }
15520
15521     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15522             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
15523         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
15524
15525         int dumpUid = 0;
15526         if (dumpPackage != null) {
15527             IPackageManager pm = AppGlobals.getPackageManager();
15528             try {
15529                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_ANY_USER, 0);
15530             } catch (RemoteException e) {
15531             }
15532         }
15533
15534         boolean printedAnything = false;
15535
15536         final long now = SystemClock.uptimeMillis();
15537
15538         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
15539             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
15540                     = mAssociations.valueAt(i1);
15541             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
15542                 SparseArray<ArrayMap<String, Association>> sourceUids
15543                         = targetComponents.valueAt(i2);
15544                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
15545                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
15546                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
15547                         Association ass = sourceProcesses.valueAt(i4);
15548                         if (dumpPackage != null) {
15549                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
15550                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
15551                                 continue;
15552                             }
15553                         }
15554                         printedAnything = true;
15555                         pw.print("  ");
15556                         pw.print(ass.mTargetProcess);
15557                         pw.print("/");
15558                         UserHandle.formatUid(pw, ass.mTargetUid);
15559                         pw.print(" <- ");
15560                         pw.print(ass.mSourceProcess);
15561                         pw.print("/");
15562                         UserHandle.formatUid(pw, ass.mSourceUid);
15563                         pw.println();
15564                         pw.print("    via ");
15565                         pw.print(ass.mTargetComponent.flattenToShortString());
15566                         pw.println();
15567                         pw.print("    ");
15568                         long dur = ass.mTime;
15569                         if (ass.mNesting > 0) {
15570                             dur += now - ass.mStartTime;
15571                         }
15572                         TimeUtils.formatDuration(dur, pw);
15573                         pw.print(" (");
15574                         pw.print(ass.mCount);
15575                         pw.print(" times)");
15576                         pw.print("  ");
15577                         for (int i=0; i<ass.mStateTimes.length; i++) {
15578                             long amt = ass.mStateTimes[i];
15579                             if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15580                                 amt += now - ass.mLastStateUptime;
15581                             }
15582                             if (amt != 0) {
15583                                 pw.print(" ");
15584                                 pw.print(ProcessList.makeProcStateString(
15585                                             i + ActivityManager.MIN_PROCESS_STATE));
15586                                 pw.print("=");
15587                                 TimeUtils.formatDuration(amt, pw);
15588                                 if ((ass.mLastState-ActivityManager.MIN_PROCESS_STATE) == i) {
15589                                     pw.print("*");
15590                                 }
15591                             }
15592                         }
15593                         pw.println();
15594                         if (ass.mNesting > 0) {
15595                             pw.print("    Currently active: ");
15596                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
15597                             pw.println();
15598                         }
15599                     }
15600                 }
15601             }
15602
15603         }
15604
15605         if (!printedAnything) {
15606             pw.println("  (nothing)");
15607         }
15608     }
15609
15610     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
15611             String header, boolean needSep) {
15612         boolean printed = false;
15613         int whichAppId = -1;
15614         if (dumpPackage != null) {
15615             try {
15616                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
15617                         dumpPackage, 0);
15618                 whichAppId = UserHandle.getAppId(info.uid);
15619             } catch (NameNotFoundException e) {
15620                 e.printStackTrace();
15621             }
15622         }
15623         for (int i=0; i<uids.size(); i++) {
15624             UidRecord uidRec = uids.valueAt(i);
15625             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
15626                 continue;
15627             }
15628             if (!printed) {
15629                 printed = true;
15630                 if (needSep) {
15631                     pw.println();
15632                 }
15633                 pw.print("  ");
15634                 pw.println(header);
15635                 needSep = true;
15636             }
15637             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
15638             pw.print(": "); pw.println(uidRec);
15639         }
15640         return printed;
15641     }
15642
15643     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15644             int opti, boolean dumpAll, String dumpPackage) {
15645         boolean needSep = false;
15646         boolean printedAnything = false;
15647         int numPers = 0;
15648
15649         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
15650
15651         if (dumpAll) {
15652             final int NP = mProcessNames.getMap().size();
15653             for (int ip=0; ip<NP; ip++) {
15654                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
15655                 final int NA = procs.size();
15656                 for (int ia=0; ia<NA; ia++) {
15657                     ProcessRecord r = procs.valueAt(ia);
15658                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15659                         continue;
15660                     }
15661                     if (!needSep) {
15662                         pw.println("  All known processes:");
15663                         needSep = true;
15664                         printedAnything = true;
15665                     }
15666                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
15667                         pw.print(" UID "); pw.print(procs.keyAt(ia));
15668                         pw.print(" "); pw.println(r);
15669                     r.dump(pw, "    ");
15670                     if (r.persistent) {
15671                         numPers++;
15672                     }
15673                 }
15674             }
15675         }
15676
15677         if (mIsolatedProcesses.size() > 0) {
15678             boolean printed = false;
15679             for (int i=0; i<mIsolatedProcesses.size(); i++) {
15680                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
15681                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15682                     continue;
15683                 }
15684                 if (!printed) {
15685                     if (needSep) {
15686                         pw.println();
15687                     }
15688                     pw.println("  Isolated process list (sorted by uid):");
15689                     printedAnything = true;
15690                     printed = true;
15691                     needSep = true;
15692                 }
15693                 pw.print("    Isolated #"); pw.print(i); pw.print(": ");
15694                 pw.println(r);
15695             }
15696         }
15697
15698         if (mActiveInstrumentation.size() > 0) {
15699             boolean printed = false;
15700             for (int i=0; i<mActiveInstrumentation.size(); i++) {
15701                 ActiveInstrumentation ai = mActiveInstrumentation.get(i);
15702                 if (dumpPackage != null && !ai.mClass.getPackageName().equals(dumpPackage)
15703                         && !ai.mTargetInfo.packageName.equals(dumpPackage)) {
15704                     continue;
15705                 }
15706                 if (!printed) {
15707                     if (needSep) {
15708                         pw.println();
15709                     }
15710                     pw.println("  Active instrumentation:");
15711                     printedAnything = true;
15712                     printed = true;
15713                     needSep = true;
15714                 }
15715                 pw.print("    Instrumentation #"); pw.print(i); pw.print(": ");
15716                 pw.println(ai);
15717                 ai.dump(pw, "      ");
15718             }
15719         }
15720
15721         if (mActiveUids.size() > 0) {
15722             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
15723                 printedAnything = needSep = true;
15724             }
15725         }
15726         if (dumpAll) {
15727             if (mValidateUids.size() > 0) {
15728                 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
15729                     printedAnything = needSep = true;
15730                 }
15731             }
15732         }
15733
15734         if (mLruProcesses.size() > 0) {
15735             if (needSep) {
15736                 pw.println();
15737             }
15738             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
15739                     pw.print(" total, non-act at ");
15740                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15741                     pw.print(", non-svc at ");
15742                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15743                     pw.println("):");
15744             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
15745             needSep = true;
15746             printedAnything = true;
15747         }
15748
15749         if (dumpAll || dumpPackage != null) {
15750             synchronized (mPidsSelfLocked) {
15751                 boolean printed = false;
15752                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
15753                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
15754                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15755                         continue;
15756                     }
15757                     if (!printed) {
15758                         if (needSep) pw.println();
15759                         needSep = true;
15760                         pw.println("  PID mappings:");
15761                         printed = true;
15762                         printedAnything = true;
15763                     }
15764                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
15765                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
15766                 }
15767             }
15768         }
15769
15770         if (mImportantProcesses.size() > 0) {
15771             synchronized (mPidsSelfLocked) {
15772                 boolean printed = false;
15773                 for (int i = 0; i< mImportantProcesses.size(); i++) {
15774                     ProcessRecord r = mPidsSelfLocked.get(
15775                             mImportantProcesses.valueAt(i).pid);
15776                     if (dumpPackage != null && (r == null
15777                             || !r.pkgList.containsKey(dumpPackage))) {
15778                         continue;
15779                     }
15780                     if (!printed) {
15781                         if (needSep) pw.println();
15782                         needSep = true;
15783                         pw.println("  Foreground Processes:");
15784                         printed = true;
15785                         printedAnything = true;
15786                     }
15787                     pw.print("    PID #"); pw.print(mImportantProcesses.keyAt(i));
15788                             pw.print(": "); pw.println(mImportantProcesses.valueAt(i));
15789                 }
15790             }
15791         }
15792
15793         if (mPersistentStartingProcesses.size() > 0) {
15794             if (needSep) pw.println();
15795             needSep = true;
15796             printedAnything = true;
15797             pw.println("  Persisent processes that are starting:");
15798             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
15799                     "Starting Norm", "Restarting PERS", dumpPackage);
15800         }
15801
15802         if (mRemovedProcesses.size() > 0) {
15803             if (needSep) pw.println();
15804             needSep = true;
15805             printedAnything = true;
15806             pw.println("  Processes that are being removed:");
15807             dumpProcessList(pw, this, mRemovedProcesses, "    ",
15808                     "Removed Norm", "Removed PERS", dumpPackage);
15809         }
15810
15811         if (mProcessesOnHold.size() > 0) {
15812             if (needSep) pw.println();
15813             needSep = true;
15814             printedAnything = true;
15815             pw.println("  Processes that are on old until the system is ready:");
15816             dumpProcessList(pw, this, mProcessesOnHold, "    ",
15817                     "OnHold Norm", "OnHold PERS", dumpPackage);
15818         }
15819
15820         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
15821
15822         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
15823         if (needSep) {
15824             printedAnything = true;
15825         }
15826
15827         if (dumpPackage == null) {
15828             pw.println();
15829             needSep = false;
15830             mUserController.dump(pw, dumpAll);
15831         }
15832         if (mHomeProcess != null && (dumpPackage == null
15833                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
15834             if (needSep) {
15835                 pw.println();
15836                 needSep = false;
15837             }
15838             pw.println("  mHomeProcess: " + mHomeProcess);
15839         }
15840         if (mPreviousProcess != null && (dumpPackage == null
15841                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
15842             if (needSep) {
15843                 pw.println();
15844                 needSep = false;
15845             }
15846             pw.println("  mPreviousProcess: " + mPreviousProcess);
15847         }
15848         if (dumpAll) {
15849             StringBuilder sb = new StringBuilder(128);
15850             sb.append("  mPreviousProcessVisibleTime: ");
15851             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
15852             pw.println(sb);
15853         }
15854         if (mHeavyWeightProcess != null && (dumpPackage == null
15855                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
15856             if (needSep) {
15857                 pw.println();
15858                 needSep = false;
15859             }
15860             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15861         }
15862         if (dumpPackage == null) {
15863             pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
15864             mStackSupervisor.dumpDisplayConfigs(pw, "  ");
15865         }
15866         if (dumpAll) {
15867             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
15868             if (mCompatModePackages.getPackages().size() > 0) {
15869                 boolean printed = false;
15870                 for (Map.Entry<String, Integer> entry
15871                         : mCompatModePackages.getPackages().entrySet()) {
15872                     String pkg = entry.getKey();
15873                     int mode = entry.getValue();
15874                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
15875                         continue;
15876                     }
15877                     if (!printed) {
15878                         pw.println("  mScreenCompatPackages:");
15879                         printed = true;
15880                     }
15881                     pw.print("    "); pw.print(pkg); pw.print(": ");
15882                             pw.print(mode); pw.println();
15883                 }
15884             }
15885             final int NI = mUidObservers.getRegisteredCallbackCount();
15886             boolean printed = false;
15887             for (int i=0; i<NI; i++) {
15888                 final UidObserverRegistration reg = (UidObserverRegistration)
15889                         mUidObservers.getRegisteredCallbackCookie(i);
15890                 if (dumpPackage == null || dumpPackage.equals(reg.pkg)) {
15891                     if (!printed) {
15892                         pw.println("  mUidObservers:");
15893                         printed = true;
15894                     }
15895                     pw.print("    "); UserHandle.formatUid(pw, reg.uid);
15896                     pw.print(" "); pw.print(reg.pkg); pw.print(":");
15897                     if ((reg.which&ActivityManager.UID_OBSERVER_IDLE) != 0) {
15898                         pw.print(" IDLE");
15899                     }
15900                     if ((reg.which&ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
15901                         pw.print(" ACT" );
15902                     }
15903                     if ((reg.which&ActivityManager.UID_OBSERVER_GONE) != 0) {
15904                         pw.print(" GONE");
15905                     }
15906                     if ((reg.which&ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
15907                         pw.print(" STATE");
15908                         pw.print(" (cut="); pw.print(reg.cutpoint);
15909                         pw.print(")");
15910                     }
15911                     pw.println();
15912                     if (reg.lastProcStates != null) {
15913                         final int NJ = reg.lastProcStates.size();
15914                         for (int j=0; j<NJ; j++) {
15915                             pw.print("      Last ");
15916                             UserHandle.formatUid(pw, reg.lastProcStates.keyAt(j));
15917                             pw.print(": "); pw.println(reg.lastProcStates.valueAt(j));
15918                         }
15919                     }
15920                 }
15921             }
15922             pw.println("  mDeviceIdleWhitelist=" + Arrays.toString(mDeviceIdleWhitelist));
15923             pw.println("  mDeviceIdleTempWhitelist=" + Arrays.toString(mDeviceIdleTempWhitelist));
15924             if (mPendingTempWhitelist.size() > 0) {
15925                 pw.println("  mPendingTempWhitelist:");
15926                 for (int i = 0; i < mPendingTempWhitelist.size(); i++) {
15927                     PendingTempWhitelist ptw = mPendingTempWhitelist.valueAt(i);
15928                     pw.print("    ");
15929                     UserHandle.formatUid(pw, ptw.targetUid);
15930                     pw.print(": ");
15931                     TimeUtils.formatDuration(ptw.duration, pw);
15932                     pw.print(" ");
15933                     pw.println(ptw.tag);
15934                 }
15935             }
15936         }
15937         if (dumpPackage == null) {
15938             pw.println("  mWakefulness="
15939                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
15940             pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
15941             pw.println("  mSleeping=" + mSleeping);
15942             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
15943             if (mRunningVoice != null) {
15944                 pw.println("  mRunningVoice=" + mRunningVoice);
15945                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
15946             }
15947         }
15948         pw.println("  mVrController=" + mVrController);
15949         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
15950                 || mOrigWaitForDebugger) {
15951             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
15952                     || dumpPackage.equals(mOrigDebugApp)) {
15953                 if (needSep) {
15954                     pw.println();
15955                     needSep = false;
15956                 }
15957                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
15958                         + " mDebugTransient=" + mDebugTransient
15959                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
15960             }
15961         }
15962         if (mCurAppTimeTracker != null) {
15963             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
15964         }
15965         if (mMemWatchProcesses.getMap().size() > 0) {
15966             pw.println("  Mem watch processes:");
15967             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
15968                     = mMemWatchProcesses.getMap();
15969             for (int i=0; i<procs.size(); i++) {
15970                 final String proc = procs.keyAt(i);
15971                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
15972                 for (int j=0; j<uids.size(); j++) {
15973                     if (needSep) {
15974                         pw.println();
15975                         needSep = false;
15976                     }
15977                     StringBuilder sb = new StringBuilder();
15978                     sb.append("    ").append(proc).append('/');
15979                     UserHandle.formatUid(sb, uids.keyAt(j));
15980                     Pair<Long, String> val = uids.valueAt(j);
15981                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
15982                     if (val.second != null) {
15983                         sb.append(", report to ").append(val.second);
15984                     }
15985                     pw.println(sb.toString());
15986                 }
15987             }
15988             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
15989             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
15990             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
15991                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
15992         }
15993         if (mTrackAllocationApp != null) {
15994             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
15995                 if (needSep) {
15996                     pw.println();
15997                     needSep = false;
15998                 }
15999                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
16000             }
16001         }
16002         if (mProfileApp != null || mProfileProc != null || (mProfilerInfo != null &&
16003                 (mProfilerInfo.profileFile != null || mProfilerInfo.profileFd != null))) {
16004             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
16005                 if (needSep) {
16006                     pw.println();
16007                     needSep = false;
16008                 }
16009                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
16010                 if (mProfilerInfo != null) {
16011                     pw.println("  mProfileFile=" + mProfilerInfo.profileFile + " mProfileFd=" +
16012                             mProfilerInfo.profileFd);
16013                     pw.println("  mSamplingInterval=" + mProfilerInfo.samplingInterval +
16014                             " mAutoStopProfiler=" + mProfilerInfo.autoStopProfiler +
16015                             " mStreamingOutput=" + mProfilerInfo.streamingOutput);
16016                     pw.println("  mProfileType=" + mProfileType);
16017                 }
16018             }
16019         }
16020         if (mNativeDebuggingApp != null) {
16021             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
16022                 if (needSep) {
16023                     pw.println();
16024                     needSep = false;
16025                 }
16026                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
16027             }
16028         }
16029         if (dumpPackage == null) {
16030             if (mAlwaysFinishActivities) {
16031                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities);
16032             }
16033             if (mController != null) {
16034                 pw.println("  mController=" + mController
16035                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
16036             }
16037             if (dumpAll) {
16038                 pw.println("  Total persistent processes: " + numPers);
16039                 pw.println("  mProcessesReady=" + mProcessesReady
16040                         + " mSystemReady=" + mSystemReady
16041                         + " mBooted=" + mBooted
16042                         + " mFactoryTest=" + mFactoryTest);
16043                 pw.println("  mBooting=" + mBooting
16044                         + " mCallFinishBooting=" + mCallFinishBooting
16045                         + " mBootAnimationComplete=" + mBootAnimationComplete);
16046                 pw.print("  mLastPowerCheckUptime=");
16047                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
16048                         pw.println("");
16049                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
16050                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
16051                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
16052                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
16053                         + " (" + mLruProcesses.size() + " total)"
16054                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
16055                         + " mNumServiceProcs=" + mNumServiceProcs
16056                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
16057                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
16058                         + " mLastMemoryLevel=" + mLastMemoryLevel
16059                         + " mLastNumProcesses=" + mLastNumProcesses);
16060                 long now = SystemClock.uptimeMillis();
16061                 pw.print("  mLastIdleTime=");
16062                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
16063                         pw.print(" mLowRamSinceLastIdle=");
16064                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
16065                         pw.println();
16066             }
16067         }
16068
16069         if (!printedAnything) {
16070             pw.println("  (nothing)");
16071         }
16072     }
16073
16074     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
16075             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
16076         if (mProcessesToGc.size() > 0) {
16077             boolean printed = false;
16078             long now = SystemClock.uptimeMillis();
16079             for (int i=0; i<mProcessesToGc.size(); i++) {
16080                 ProcessRecord proc = mProcessesToGc.get(i);
16081                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
16082                     continue;
16083                 }
16084                 if (!printed) {
16085                     if (needSep) pw.println();
16086                     needSep = true;
16087                     pw.println("  Processes that are waiting to GC:");
16088                     printed = true;
16089                 }
16090                 pw.print("    Process "); pw.println(proc);
16091                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
16092                         pw.print(", last gced=");
16093                         pw.print(now-proc.lastRequestedGc);
16094                         pw.print(" ms ago, last lowMem=");
16095                         pw.print(now-proc.lastLowMemory);
16096                         pw.println(" ms ago");
16097
16098             }
16099         }
16100         return needSep;
16101     }
16102
16103     void printOomLevel(PrintWriter pw, String name, int adj) {
16104         pw.print("    ");
16105         if (adj >= 0) {
16106             pw.print(' ');
16107             if (adj < 10) pw.print(' ');
16108         } else {
16109             if (adj > -10) pw.print(' ');
16110         }
16111         pw.print(adj);
16112         pw.print(": ");
16113         pw.print(name);
16114         pw.print(" (");
16115         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
16116         pw.println(")");
16117     }
16118
16119     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16120             int opti, boolean dumpAll) {
16121         boolean needSep = false;
16122
16123         if (mLruProcesses.size() > 0) {
16124             if (needSep) pw.println();
16125             needSep = true;
16126             pw.println("  OOM levels:");
16127             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
16128             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
16129             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
16130             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
16131             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
16132             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
16133             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
16134             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
16135             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
16136             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
16137             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
16138             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
16139             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
16140             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
16141
16142             if (needSep) pw.println();
16143             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
16144                     pw.print(" total, non-act at ");
16145                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
16146                     pw.print(", non-svc at ");
16147                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
16148                     pw.println("):");
16149             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
16150             needSep = true;
16151         }
16152
16153         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
16154
16155         pw.println();
16156         pw.println("  mHomeProcess: " + mHomeProcess);
16157         pw.println("  mPreviousProcess: " + mPreviousProcess);
16158         if (mHeavyWeightProcess != null) {
16159             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
16160         }
16161
16162         return true;
16163     }
16164
16165     /**
16166      * There are three ways to call this:
16167      *  - no provider specified: dump all the providers
16168      *  - a flattened component name that matched an existing provider was specified as the
16169      *    first arg: dump that one provider
16170      *  - the first arg isn't the flattened component name of an existing provider:
16171      *    dump all providers whose component contains the first arg as a substring
16172      */
16173     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16174             int opti, boolean dumpAll) {
16175         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
16176     }
16177
16178     static class ItemMatcher {
16179         ArrayList<ComponentName> components;
16180         ArrayList<String> strings;
16181         ArrayList<Integer> objects;
16182         boolean all;
16183
16184         ItemMatcher() {
16185             all = true;
16186         }
16187
16188         void build(String name) {
16189             ComponentName componentName = ComponentName.unflattenFromString(name);
16190             if (componentName != null) {
16191                 if (components == null) {
16192                     components = new ArrayList<ComponentName>();
16193                 }
16194                 components.add(componentName);
16195                 all = false;
16196             } else {
16197                 int objectId = 0;
16198                 // Not a '/' separated full component name; maybe an object ID?
16199                 try {
16200                     objectId = Integer.parseInt(name, 16);
16201                     if (objects == null) {
16202                         objects = new ArrayList<Integer>();
16203                     }
16204                     objects.add(objectId);
16205                     all = false;
16206                 } catch (RuntimeException e) {
16207                     // Not an integer; just do string match.
16208                     if (strings == null) {
16209                         strings = new ArrayList<String>();
16210                     }
16211                     strings.add(name);
16212                     all = false;
16213                 }
16214             }
16215         }
16216
16217         int build(String[] args, int opti) {
16218             for (; opti<args.length; opti++) {
16219                 String name = args[opti];
16220                 if ("--".equals(name)) {
16221                     return opti+1;
16222                 }
16223                 build(name);
16224             }
16225             return opti;
16226         }
16227
16228         boolean match(Object object, ComponentName comp) {
16229             if (all) {
16230                 return true;
16231             }
16232             if (components != null) {
16233                 for (int i=0; i<components.size(); i++) {
16234                     if (components.get(i).equals(comp)) {
16235                         return true;
16236                     }
16237                 }
16238             }
16239             if (objects != null) {
16240                 for (int i=0; i<objects.size(); i++) {
16241                     if (System.identityHashCode(object) == objects.get(i)) {
16242                         return true;
16243                     }
16244                 }
16245             }
16246             if (strings != null) {
16247                 String flat = comp.flattenToString();
16248                 for (int i=0; i<strings.size(); i++) {
16249                     if (flat.contains(strings.get(i))) {
16250                         return true;
16251                     }
16252                 }
16253             }
16254             return false;
16255         }
16256     }
16257
16258     /**
16259      * There are three things that cmd can be:
16260      *  - a flattened component name that matches an existing activity
16261      *  - the cmd arg isn't the flattened component name of an existing activity:
16262      *    dump all activity whose component contains the cmd as a substring
16263      *  - A hex number of the ActivityRecord object instance.
16264      *
16265      *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
16266      *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
16267      */
16268     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
16269             int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
16270         ArrayList<ActivityRecord> activities;
16271
16272         synchronized (this) {
16273             activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
16274                     dumpFocusedStackOnly);
16275         }
16276
16277         if (activities.size() <= 0) {
16278             return false;
16279         }
16280
16281         String[] newArgs = new String[args.length - opti];
16282         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
16283
16284         TaskRecord lastTask = null;
16285         boolean needSep = false;
16286         for (int i=activities.size()-1; i>=0; i--) {
16287             ActivityRecord r = activities.get(i);
16288             if (needSep) {
16289                 pw.println();
16290             }
16291             needSep = true;
16292             synchronized (this) {
16293                 final TaskRecord task = r.getTask();
16294                 if (lastTask != task) {
16295                     lastTask = task;
16296                     pw.print("TASK "); pw.print(lastTask.affinity);
16297                             pw.print(" id="); pw.print(lastTask.taskId);
16298                             pw.print(" userId="); pw.println(lastTask.userId);
16299                     if (dumpAll) {
16300                         lastTask.dump(pw, "  ");
16301                     }
16302                 }
16303             }
16304             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
16305         }
16306         return true;
16307     }
16308
16309     /**
16310      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
16311      * there is a thread associated with the activity.
16312      */
16313     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
16314             final ActivityRecord r, String[] args, boolean dumpAll) {
16315         String innerPrefix = prefix + "  ";
16316         synchronized (this) {
16317             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
16318                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
16319                     pw.print(" pid=");
16320                     if (r.app != null) pw.println(r.app.pid);
16321                     else pw.println("(not running)");
16322             if (dumpAll) {
16323                 r.dump(pw, innerPrefix);
16324             }
16325         }
16326         if (r.app != null && r.app.thread != null) {
16327             // flush anything that is already in the PrintWriter since the thread is going
16328             // to write to the file descriptor directly
16329             pw.flush();
16330             try {
16331                 TransferPipe tp = new TransferPipe();
16332                 try {
16333                     r.app.thread.dumpActivity(tp.getWriteFd(),
16334                             r.appToken, innerPrefix, args);
16335                     tp.go(fd);
16336                 } finally {
16337                     tp.kill();
16338                 }
16339             } catch (IOException e) {
16340                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
16341             } catch (RemoteException e) {
16342                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
16343             }
16344         }
16345     }
16346
16347     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16348             int opti, boolean dumpAll, String dumpPackage) {
16349         boolean needSep = false;
16350         boolean onlyHistory = false;
16351         boolean printedAnything = false;
16352
16353         if ("history".equals(dumpPackage)) {
16354             if (opti < args.length && "-s".equals(args[opti])) {
16355                 dumpAll = false;
16356             }
16357             onlyHistory = true;
16358             dumpPackage = null;
16359         }
16360
16361         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
16362         if (!onlyHistory && dumpAll) {
16363             if (mRegisteredReceivers.size() > 0) {
16364                 boolean printed = false;
16365                 Iterator it = mRegisteredReceivers.values().iterator();
16366                 while (it.hasNext()) {
16367                     ReceiverList r = (ReceiverList)it.next();
16368                     if (dumpPackage != null && (r.app == null ||
16369                             !dumpPackage.equals(r.app.info.packageName))) {
16370                         continue;
16371                     }
16372                     if (!printed) {
16373                         pw.println("  Registered Receivers:");
16374                         needSep = true;
16375                         printed = true;
16376                         printedAnything = true;
16377                     }
16378                     pw.print("  * "); pw.println(r);
16379                     r.dump(pw, "    ");
16380                 }
16381             }
16382
16383             if (mReceiverResolver.dump(pw, needSep ?
16384                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
16385                     "    ", dumpPackage, false, false)) {
16386                 needSep = true;
16387                 printedAnything = true;
16388             }
16389         }
16390
16391         for (BroadcastQueue q : mBroadcastQueues) {
16392             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
16393             printedAnything |= needSep;
16394         }
16395
16396         needSep = true;
16397
16398         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
16399             for (int user=0; user<mStickyBroadcasts.size(); user++) {
16400                 if (needSep) {
16401                     pw.println();
16402                 }
16403                 needSep = true;
16404                 printedAnything = true;
16405                 pw.print("  Sticky broadcasts for user ");
16406                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
16407                 StringBuilder sb = new StringBuilder(128);
16408                 for (Map.Entry<String, ArrayList<Intent>> ent
16409                         : mStickyBroadcasts.valueAt(user).entrySet()) {
16410                     pw.print("  * Sticky action "); pw.print(ent.getKey());
16411                     if (dumpAll) {
16412                         pw.println(":");
16413                         ArrayList<Intent> intents = ent.getValue();
16414                         final int N = intents.size();
16415                         for (int i=0; i<N; i++) {
16416                             sb.setLength(0);
16417                             sb.append("    Intent: ");
16418                             intents.get(i).toShortString(sb, false, true, false, false);
16419                             pw.println(sb.toString());
16420                             Bundle bundle = intents.get(i).getExtras();
16421                             if (bundle != null) {
16422                                 pw.print("      ");
16423                                 pw.println(bundle.toString());
16424                             }
16425                         }
16426                     } else {
16427                         pw.println("");
16428                     }
16429                 }
16430             }
16431         }
16432
16433         if (!onlyHistory && dumpAll) {
16434             pw.println();
16435             for (BroadcastQueue queue : mBroadcastQueues) {
16436                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
16437                         + queue.mBroadcastsScheduled);
16438             }
16439             pw.println("  mHandler:");
16440             mHandler.dump(new PrintWriterPrinter(pw), "    ");
16441             needSep = true;
16442             printedAnything = true;
16443         }
16444
16445         if (!printedAnything) {
16446             pw.println("  (nothing)");
16447         }
16448     }
16449
16450     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16451             int opti, boolean dumpAll, String dumpPackage) {
16452         if (mCurBroadcastStats == null) {
16453             return;
16454         }
16455
16456         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
16457         final long now = SystemClock.elapsedRealtime();
16458         if (mLastBroadcastStats != null) {
16459             pw.print("  Last stats (from ");
16460             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
16461             pw.print(" to ");
16462             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
16463             pw.print(", ");
16464             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
16465                     - mLastBroadcastStats.mStartUptime, pw);
16466             pw.println(" uptime):");
16467             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16468                 pw.println("    (nothing)");
16469             }
16470             pw.println();
16471         }
16472         pw.print("  Current stats (from ");
16473         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
16474         pw.print(" to now, ");
16475         TimeUtils.formatDuration(SystemClock.uptimeMillis()
16476                 - mCurBroadcastStats.mStartUptime, pw);
16477         pw.println(" uptime):");
16478         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
16479             pw.println("    (nothing)");
16480         }
16481     }
16482
16483     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16484             int opti, boolean fullCheckin, String dumpPackage) {
16485         if (mCurBroadcastStats == null) {
16486             return;
16487         }
16488
16489         if (mLastBroadcastStats != null) {
16490             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16491             if (fullCheckin) {
16492                 mLastBroadcastStats = null;
16493                 return;
16494             }
16495         }
16496         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
16497         if (fullCheckin) {
16498             mCurBroadcastStats = null;
16499         }
16500     }
16501
16502     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16503             int opti, boolean dumpAll, String dumpPackage) {
16504         boolean needSep;
16505         boolean printedAnything = false;
16506
16507         ItemMatcher matcher = new ItemMatcher();
16508         matcher.build(args, opti);
16509
16510         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
16511
16512         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
16513         printedAnything |= needSep;
16514
16515         if (mLaunchingProviders.size() > 0) {
16516             boolean printed = false;
16517             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
16518                 ContentProviderRecord r = mLaunchingProviders.get(i);
16519                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
16520                     continue;
16521                 }
16522                 if (!printed) {
16523                     if (needSep) pw.println();
16524                     needSep = true;
16525                     pw.println("  Launching content providers:");
16526                     printed = true;
16527                     printedAnything = true;
16528                 }
16529                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
16530                         pw.println(r);
16531             }
16532         }
16533
16534         if (!printedAnything) {
16535             pw.println("  (nothing)");
16536         }
16537     }
16538
16539     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16540             int opti, boolean dumpAll, String dumpPackage) {
16541         boolean needSep = false;
16542         boolean printedAnything = false;
16543
16544         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
16545
16546         if (mGrantedUriPermissions.size() > 0) {
16547             boolean printed = false;
16548             int dumpUid = -2;
16549             if (dumpPackage != null) {
16550                 try {
16551                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
16552                             MATCH_ANY_USER, 0);
16553                 } catch (NameNotFoundException e) {
16554                     dumpUid = -1;
16555                 }
16556             }
16557             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
16558                 int uid = mGrantedUriPermissions.keyAt(i);
16559                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
16560                     continue;
16561                 }
16562                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
16563                 if (!printed) {
16564                     if (needSep) pw.println();
16565                     needSep = true;
16566                     pw.println("  Granted Uri Permissions:");
16567                     printed = true;
16568                     printedAnything = true;
16569                 }
16570                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
16571                 for (UriPermission perm : perms.values()) {
16572                     pw.print("    "); pw.println(perm);
16573                     if (dumpAll) {
16574                         perm.dump(pw, "      ");
16575                     }
16576                 }
16577             }
16578         }
16579
16580         if (!printedAnything) {
16581             pw.println("  (nothing)");
16582         }
16583     }
16584
16585     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
16586             int opti, boolean dumpAll, String dumpPackage) {
16587         boolean printed = false;
16588
16589         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
16590
16591         if (mIntentSenderRecords.size() > 0) {
16592             // Organize these by package name, so they are easier to read.
16593             final ArrayMap<String, ArrayList<PendingIntentRecord>> byPackage = new ArrayMap<>();
16594             final ArrayList<WeakReference<PendingIntentRecord>> weakRefs = new ArrayList<>();
16595             final Iterator<WeakReference<PendingIntentRecord>> it
16596                     = mIntentSenderRecords.values().iterator();
16597             while (it.hasNext()) {
16598                 WeakReference<PendingIntentRecord> ref = it.next();
16599                 PendingIntentRecord rec = ref != null ? ref.get() : null;
16600                 if (rec == null) {
16601                     weakRefs.add(ref);
16602                     continue;
16603                 }
16604                 if (dumpPackage != null && !dumpPackage.equals(rec.key.packageName)) {
16605                     continue;
16606                 }
16607                 ArrayList<PendingIntentRecord> list = byPackage.get(rec.key.packageName);
16608                 if (list == null) {
16609                     list = new ArrayList<>();
16610                     byPackage.put(rec.key.packageName, list);
16611                 }
16612                 list.add(rec);
16613             }
16614             for (int i = 0; i < byPackage.size(); i++) {
16615                 ArrayList<PendingIntentRecord> intents = byPackage.valueAt(i);
16616                 printed = true;
16617                 pw.print("  * "); pw.print(byPackage.keyAt(i));
16618                 pw.print(": "); pw.print(intents.size()); pw.println(" items");
16619                 for (int j = 0; j < intents.size(); j++) {
16620                     pw.print("    #"); pw.print(j); pw.print(": "); pw.println(intents.get(j));
16621                     if (dumpAll) {
16622                         intents.get(j).dump(pw, "      ");
16623                     }
16624                 }
16625             }
16626             if (weakRefs.size() > 0) {
16627                 printed = true;
16628                 pw.println("  * WEAK REFS:");
16629                 for (int i = 0; i < weakRefs.size(); i++) {
16630                     pw.print("    #"); pw.print(i); pw.print(": "); pw.println(weakRefs.get(i));
16631                 }
16632             }
16633         }
16634
16635         if (!printed) {
16636             pw.println("  (nothing)");
16637         }
16638     }
16639
16640     private static final int dumpProcessList(PrintWriter pw,
16641             ActivityManagerService service, List list,
16642             String prefix, String normalLabel, String persistentLabel,
16643             String dumpPackage) {
16644         int numPers = 0;
16645         final int N = list.size()-1;
16646         for (int i=N; i>=0; i--) {
16647             ProcessRecord r = (ProcessRecord)list.get(i);
16648             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
16649                 continue;
16650             }
16651             pw.println(String.format("%s%s #%2d: %s",
16652                     prefix, (r.persistent ? persistentLabel : normalLabel),
16653                     i, r.toString()));
16654             if (r.persistent) {
16655                 numPers++;
16656             }
16657         }
16658         return numPers;
16659     }
16660
16661     private static final boolean dumpProcessOomList(PrintWriter pw,
16662             ActivityManagerService service, List<ProcessRecord> origList,
16663             String prefix, String normalLabel, String persistentLabel,
16664             boolean inclDetails, String dumpPackage) {
16665
16666         ArrayList<Pair<ProcessRecord, Integer>> list
16667                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
16668         for (int i=0; i<origList.size(); i++) {
16669             ProcessRecord r = origList.get(i);
16670             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
16671                 continue;
16672             }
16673             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
16674         }
16675
16676         if (list.size() <= 0) {
16677             return false;
16678         }
16679
16680         Comparator<Pair<ProcessRecord, Integer>> comparator
16681                 = new Comparator<Pair<ProcessRecord, Integer>>() {
16682             @Override
16683             public int compare(Pair<ProcessRecord, Integer> object1,
16684                     Pair<ProcessRecord, Integer> object2) {
16685                 if (object1.first.setAdj != object2.first.setAdj) {
16686                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
16687                 }
16688                 if (object1.first.setProcState != object2.first.setProcState) {
16689                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
16690                 }
16691                 if (object1.second.intValue() != object2.second.intValue()) {
16692                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
16693                 }
16694                 return 0;
16695             }
16696         };
16697
16698         Collections.sort(list, comparator);
16699
16700         final long curUptime = SystemClock.uptimeMillis();
16701         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
16702
16703         for (int i=list.size()-1; i>=0; i--) {
16704             ProcessRecord r = list.get(i).first;
16705             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
16706             char schedGroup;
16707             switch (r.setSchedGroup) {
16708                 case ProcessList.SCHED_GROUP_BACKGROUND:
16709                     schedGroup = 'B';
16710                     break;
16711                 case ProcessList.SCHED_GROUP_DEFAULT:
16712                     schedGroup = 'F';
16713                     break;
16714                 case ProcessList.SCHED_GROUP_TOP_APP:
16715                     schedGroup = 'T';
16716                     break;
16717                 default:
16718                     schedGroup = '?';
16719                     break;
16720             }
16721             char foreground;
16722             if (r.foregroundActivities) {
16723                 foreground = 'A';
16724             } else if (r.foregroundServices) {
16725                 foreground = 'S';
16726             } else {
16727                 foreground = ' ';
16728             }
16729             String procState = ProcessList.makeProcStateString(r.curProcState);
16730             pw.print(prefix);
16731             pw.print(r.persistent ? persistentLabel : normalLabel);
16732             pw.print(" #");
16733             int num = (origList.size()-1)-list.get(i).second;
16734             if (num < 10) pw.print(' ');
16735             pw.print(num);
16736             pw.print(": ");
16737             pw.print(oomAdj);
16738             pw.print(' ');
16739             pw.print(schedGroup);
16740             pw.print('/');
16741             pw.print(foreground);
16742             pw.print('/');
16743             pw.print(procState);
16744             pw.print(" trm:");
16745             if (r.trimMemoryLevel < 10) pw.print(' ');
16746             pw.print(r.trimMemoryLevel);
16747             pw.print(' ');
16748             pw.print(r.toShortString());
16749             pw.print(" (");
16750             pw.print(r.adjType);
16751             pw.println(')');
16752             if (r.adjSource != null || r.adjTarget != null) {
16753                 pw.print(prefix);
16754                 pw.print("    ");
16755                 if (r.adjTarget instanceof ComponentName) {
16756                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
16757                 } else if (r.adjTarget != null) {
16758                     pw.print(r.adjTarget.toString());
16759                 } else {
16760                     pw.print("{null}");
16761                 }
16762                 pw.print("<=");
16763                 if (r.adjSource instanceof ProcessRecord) {
16764                     pw.print("Proc{");
16765                     pw.print(((ProcessRecord)r.adjSource).toShortString());
16766                     pw.println("}");
16767                 } else if (r.adjSource != null) {
16768                     pw.println(r.adjSource.toString());
16769                 } else {
16770                     pw.println("{null}");
16771                 }
16772             }
16773             if (inclDetails) {
16774                 pw.print(prefix);
16775                 pw.print("    ");
16776                 pw.print("oom: max="); pw.print(r.maxAdj);
16777                 pw.print(" curRaw="); pw.print(r.curRawAdj);
16778                 pw.print(" setRaw="); pw.print(r.setRawAdj);
16779                 pw.print(" cur="); pw.print(r.curAdj);
16780                 pw.print(" set="); pw.println(r.setAdj);
16781                 pw.print(prefix);
16782                 pw.print("    ");
16783                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
16784                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
16785                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
16786                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
16787                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
16788                 pw.println();
16789                 pw.print(prefix);
16790                 pw.print("    ");
16791                 pw.print("cached="); pw.print(r.cached);
16792                 pw.print(" empty="); pw.print(r.empty);
16793                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
16794
16795                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
16796                     if (r.lastCpuTime != 0) {
16797                         long timeUsed = r.curCpuTime - r.lastCpuTime;
16798                         pw.print(prefix);
16799                         pw.print("    ");
16800                         pw.print("run cpu over ");
16801                         TimeUtils.formatDuration(uptimeSince, pw);
16802                         pw.print(" used ");
16803                         TimeUtils.formatDuration(timeUsed, pw);
16804                         pw.print(" (");
16805                         pw.print((timeUsed*100)/uptimeSince);
16806                         pw.println("%)");
16807                     }
16808                 }
16809             }
16810         }
16811         return true;
16812     }
16813
16814     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
16815             String[] args) {
16816         ArrayList<ProcessRecord> procs;
16817         synchronized (this) {
16818             if (args != null && args.length > start
16819                     && args[start].charAt(0) != '-') {
16820                 procs = new ArrayList<ProcessRecord>();
16821                 int pid = -1;
16822                 try {
16823                     pid = Integer.parseInt(args[start]);
16824                 } catch (NumberFormatException e) {
16825                 }
16826                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16827                     ProcessRecord proc = mLruProcesses.get(i);
16828                     if (proc.pid == pid) {
16829                         procs.add(proc);
16830                     } else if (allPkgs && proc.pkgList != null
16831                             && proc.pkgList.containsKey(args[start])) {
16832                         procs.add(proc);
16833                     } else if (proc.processName.equals(args[start])) {
16834                         procs.add(proc);
16835                     }
16836                 }
16837                 if (procs.size() <= 0) {
16838                     return null;
16839                 }
16840             } else {
16841                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
16842             }
16843         }
16844         return procs;
16845     }
16846
16847     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
16848             PrintWriter pw, String[] args) {
16849         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16850         if (procs == null) {
16851             pw.println("No process found for: " + args[0]);
16852             return;
16853         }
16854
16855         long uptime = SystemClock.uptimeMillis();
16856         long realtime = SystemClock.elapsedRealtime();
16857         pw.println("Applications Graphics Acceleration Info:");
16858         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16859
16860         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16861             ProcessRecord r = procs.get(i);
16862             if (r.thread != null) {
16863                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
16864                 pw.flush();
16865                 try {
16866                     TransferPipe tp = new TransferPipe();
16867                     try {
16868                         r.thread.dumpGfxInfo(tp.getWriteFd(), args);
16869                         tp.go(fd);
16870                     } finally {
16871                         tp.kill();
16872                     }
16873                 } catch (IOException e) {
16874                     pw.println("Failure while dumping the app: " + r);
16875                     pw.flush();
16876                 } catch (RemoteException e) {
16877                     pw.println("Got a RemoteException while dumping the app " + r);
16878                     pw.flush();
16879                 }
16880             }
16881         }
16882     }
16883
16884     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
16885         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
16886         if (procs == null) {
16887             pw.println("No process found for: " + args[0]);
16888             return;
16889         }
16890
16891         pw.println("Applications Database Info:");
16892
16893         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16894             ProcessRecord r = procs.get(i);
16895             if (r.thread != null) {
16896                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
16897                 pw.flush();
16898                 try {
16899                     TransferPipe tp = new TransferPipe();
16900                     try {
16901                         r.thread.dumpDbInfo(tp.getWriteFd(), args);
16902                         tp.go(fd);
16903                     } finally {
16904                         tp.kill();
16905                     }
16906                 } catch (IOException e) {
16907                     pw.println("Failure while dumping the app: " + r);
16908                     pw.flush();
16909                 } catch (RemoteException e) {
16910                     pw.println("Got a RemoteException while dumping the app " + r);
16911                     pw.flush();
16912                 }
16913             }
16914         }
16915     }
16916
16917     final static class MemItem {
16918         final boolean isProc;
16919         final String label;
16920         final String shortLabel;
16921         final long pss;
16922         final long swapPss;
16923         final int id;
16924         final boolean hasActivities;
16925         ArrayList<MemItem> subitems;
16926
16927         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
16928                 boolean _hasActivities) {
16929             isProc = true;
16930             label = _label;
16931             shortLabel = _shortLabel;
16932             pss = _pss;
16933             swapPss = _swapPss;
16934             id = _id;
16935             hasActivities = _hasActivities;
16936         }
16937
16938         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
16939             isProc = false;
16940             label = _label;
16941             shortLabel = _shortLabel;
16942             pss = _pss;
16943             swapPss = _swapPss;
16944             id = _id;
16945             hasActivities = false;
16946         }
16947     }
16948
16949     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
16950             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
16951         if (sort && !isCompact) {
16952             Collections.sort(items, new Comparator<MemItem>() {
16953                 @Override
16954                 public int compare(MemItem lhs, MemItem rhs) {
16955                     if (lhs.pss < rhs.pss) {
16956                         return 1;
16957                     } else if (lhs.pss > rhs.pss) {
16958                         return -1;
16959                     }
16960                     return 0;
16961                 }
16962             });
16963         }
16964
16965         for (int i=0; i<items.size(); i++) {
16966             MemItem mi = items.get(i);
16967             if (!isCompact) {
16968                 if (dumpSwapPss) {
16969                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
16970                             mi.label, stringifyKBSize(mi.swapPss));
16971                 } else {
16972                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
16973                 }
16974             } else if (mi.isProc) {
16975                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
16976                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
16977                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
16978                 pw.println(mi.hasActivities ? ",a" : ",e");
16979             } else {
16980                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
16981                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
16982             }
16983             if (mi.subitems != null) {
16984                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
16985                         true, isCompact, dumpSwapPss);
16986             }
16987         }
16988     }
16989
16990     // These are in KB.
16991     static final long[] DUMP_MEM_BUCKETS = new long[] {
16992         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
16993         120*1024, 160*1024, 200*1024,
16994         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
16995         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
16996     };
16997
16998     static final void appendMemBucket(StringBuilder out, long memKB, String label,
16999             boolean stackLike) {
17000         int start = label.lastIndexOf('.');
17001         if (start >= 0) start++;
17002         else start = 0;
17003         int end = label.length();
17004         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
17005             if (DUMP_MEM_BUCKETS[i] >= memKB) {
17006                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
17007                 out.append(bucket);
17008                 out.append(stackLike ? "MB." : "MB ");
17009                 out.append(label, start, end);
17010                 return;
17011             }
17012         }
17013         out.append(memKB/1024);
17014         out.append(stackLike ? "MB." : "MB ");
17015         out.append(label, start, end);
17016     }
17017
17018     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
17019             ProcessList.NATIVE_ADJ,
17020             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
17021             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
17022             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
17023             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
17024             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
17025             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
17026     };
17027     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
17028             "Native",
17029             "System", "Persistent", "Persistent Service", "Foreground",
17030             "Visible", "Perceptible",
17031             "Heavy Weight", "Backup",
17032             "A Services", "Home",
17033             "Previous", "B Services", "Cached"
17034     };
17035     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
17036             "native",
17037             "sys", "pers", "persvc", "fore",
17038             "vis", "percept",
17039             "heavy", "backup",
17040             "servicea", "home",
17041             "prev", "serviceb", "cached"
17042     };
17043
17044     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
17045             long realtime, boolean isCheckinRequest, boolean isCompact) {
17046         if (isCompact) {
17047             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
17048         }
17049         if (isCheckinRequest || isCompact) {
17050             // short checkin version
17051             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
17052         } else {
17053             pw.println("Applications Memory Usage (in Kilobytes):");
17054             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
17055         }
17056     }
17057
17058     private static final int KSM_SHARED = 0;
17059     private static final int KSM_SHARING = 1;
17060     private static final int KSM_UNSHARED = 2;
17061     private static final int KSM_VOLATILE = 3;
17062
17063     private final long[] getKsmInfo() {
17064         long[] longOut = new long[4];
17065         final int[] SINGLE_LONG_FORMAT = new int[] {
17066             PROC_SPACE_TERM| PROC_OUT_LONG
17067         };
17068         long[] longTmp = new long[1];
17069         readProcFile("/sys/kernel/mm/ksm/pages_shared",
17070                 SINGLE_LONG_FORMAT, null, longTmp, null);
17071         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17072         longTmp[0] = 0;
17073         readProcFile("/sys/kernel/mm/ksm/pages_sharing",
17074                 SINGLE_LONG_FORMAT, null, longTmp, null);
17075         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17076         longTmp[0] = 0;
17077         readProcFile("/sys/kernel/mm/ksm/pages_unshared",
17078                 SINGLE_LONG_FORMAT, null, longTmp, null);
17079         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17080         longTmp[0] = 0;
17081         readProcFile("/sys/kernel/mm/ksm/pages_volatile",
17082                 SINGLE_LONG_FORMAT, null, longTmp, null);
17083         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
17084         return longOut;
17085     }
17086
17087     private static String stringifySize(long size, int order) {
17088         Locale locale = Locale.US;
17089         switch (order) {
17090             case 1:
17091                 return String.format(locale, "%,13d", size);
17092             case 1024:
17093                 return String.format(locale, "%,9dK", size / 1024);
17094             case 1024 * 1024:
17095                 return String.format(locale, "%,5dM", size / 1024 / 1024);
17096             case 1024 * 1024 * 1024:
17097                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
17098             default:
17099                 throw new IllegalArgumentException("Invalid size order");
17100         }
17101     }
17102
17103     private static String stringifyKBSize(long size) {
17104         return stringifySize(size * 1024, 1024);
17105     }
17106
17107     // Update this version number in case you change the 'compact' format
17108     private static final int MEMINFO_COMPACT_VERSION = 1;
17109
17110     final void dumpApplicationMemoryUsage(FileDescriptor fd,
17111             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
17112         boolean dumpDetails = false;
17113         boolean dumpFullDetails = false;
17114         boolean dumpDalvik = false;
17115         boolean dumpSummaryOnly = false;
17116         boolean dumpUnreachable = false;
17117         boolean oomOnly = false;
17118         boolean isCompact = false;
17119         boolean localOnly = false;
17120         boolean packages = false;
17121         boolean isCheckinRequest = false;
17122         boolean dumpSwapPss = false;
17123
17124         int opti = 0;
17125         while (opti < args.length) {
17126             String opt = args[opti];
17127             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
17128                 break;
17129             }
17130             opti++;
17131             if ("-a".equals(opt)) {
17132                 dumpDetails = true;
17133                 dumpFullDetails = true;
17134                 dumpDalvik = true;
17135                 dumpSwapPss = true;
17136             } else if ("-d".equals(opt)) {
17137                 dumpDalvik = true;
17138             } else if ("-c".equals(opt)) {
17139                 isCompact = true;
17140             } else if ("-s".equals(opt)) {
17141                 dumpDetails = true;
17142                 dumpSummaryOnly = true;
17143             } else if ("-S".equals(opt)) {
17144                 dumpSwapPss = true;
17145             } else if ("--unreachable".equals(opt)) {
17146                 dumpUnreachable = true;
17147             } else if ("--oom".equals(opt)) {
17148                 oomOnly = true;
17149             } else if ("--local".equals(opt)) {
17150                 localOnly = true;
17151             } else if ("--package".equals(opt)) {
17152                 packages = true;
17153             } else if ("--checkin".equals(opt)) {
17154                 isCheckinRequest = true;
17155
17156             } else if ("-h".equals(opt)) {
17157                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
17158                 pw.println("  -a: include all available information for each process.");
17159                 pw.println("  -d: include dalvik details.");
17160                 pw.println("  -c: dump in a compact machine-parseable representation.");
17161                 pw.println("  -s: dump only summary of application memory usage.");
17162                 pw.println("  -S: dump also SwapPss.");
17163                 pw.println("  --oom: only show processes organized by oom adj.");
17164                 pw.println("  --local: only collect details locally, don't call process.");
17165                 pw.println("  --package: interpret process arg as package, dumping all");
17166                 pw.println("             processes that have loaded that package.");
17167                 pw.println("  --checkin: dump data for a checkin");
17168                 pw.println("If [process] is specified it can be the name or ");
17169                 pw.println("pid of a specific process to dump.");
17170                 return;
17171             } else {
17172                 pw.println("Unknown argument: " + opt + "; use -h for help");
17173             }
17174         }
17175
17176         long uptime = SystemClock.uptimeMillis();
17177         long realtime = SystemClock.elapsedRealtime();
17178         final long[] tmpLong = new long[1];
17179
17180         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
17181         if (procs == null) {
17182             // No Java processes.  Maybe they want to print a native process.
17183             if (args != null && args.length > opti
17184                     && args[opti].charAt(0) != '-') {
17185                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
17186                         = new ArrayList<ProcessCpuTracker.Stats>();
17187                 updateCpuStatsNow();
17188                 int findPid = -1;
17189                 try {
17190                     findPid = Integer.parseInt(args[opti]);
17191                 } catch (NumberFormatException e) {
17192                 }
17193                 synchronized (mProcessCpuTracker) {
17194                     final int N = mProcessCpuTracker.countStats();
17195                     for (int i=0; i<N; i++) {
17196                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17197                         if (st.pid == findPid || (st.baseName != null
17198                                 && st.baseName.equals(args[opti]))) {
17199                             nativeProcs.add(st);
17200                         }
17201                     }
17202                 }
17203                 if (nativeProcs.size() > 0) {
17204                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
17205                             isCompact);
17206                     Debug.MemoryInfo mi = null;
17207                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
17208                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
17209                         final int pid = r.pid;
17210                         if (!isCheckinRequest && dumpDetails) {
17211                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
17212                         }
17213                         if (mi == null) {
17214                             mi = new Debug.MemoryInfo();
17215                         }
17216                         if (dumpDetails || (!brief && !oomOnly)) {
17217                             Debug.getMemoryInfo(pid, mi);
17218                         } else {
17219                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17220                             mi.dalvikPrivateDirty = (int)tmpLong[0];
17221                         }
17222                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17223                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
17224                         if (isCheckinRequest) {
17225                             pw.println();
17226                         }
17227                     }
17228                     return;
17229                 }
17230             }
17231             pw.println("No process found for: " + args[opti]);
17232             return;
17233         }
17234
17235         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
17236             dumpDetails = true;
17237         }
17238
17239         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
17240
17241         String[] innerArgs = new String[args.length-opti];
17242         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
17243
17244         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
17245         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
17246         long nativePss = 0;
17247         long nativeSwapPss = 0;
17248         long dalvikPss = 0;
17249         long dalvikSwapPss = 0;
17250         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17251                 EmptyArray.LONG;
17252         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
17253                 EmptyArray.LONG;
17254         long otherPss = 0;
17255         long otherSwapPss = 0;
17256         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17257         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
17258
17259         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17260         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
17261         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
17262                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
17263
17264         long totalPss = 0;
17265         long totalSwapPss = 0;
17266         long cachedPss = 0;
17267         long cachedSwapPss = 0;
17268         boolean hasSwapPss = false;
17269
17270         Debug.MemoryInfo mi = null;
17271         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
17272             final ProcessRecord r = procs.get(i);
17273             final IApplicationThread thread;
17274             final int pid;
17275             final int oomAdj;
17276             final boolean hasActivities;
17277             synchronized (this) {
17278                 thread = r.thread;
17279                 pid = r.pid;
17280                 oomAdj = r.getSetAdjWithServices();
17281                 hasActivities = r.activities.size() > 0;
17282             }
17283             if (thread != null) {
17284                 if (!isCheckinRequest && dumpDetails) {
17285                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
17286                 }
17287                 if (mi == null) {
17288                     mi = new Debug.MemoryInfo();
17289                 }
17290                 if (dumpDetails || (!brief && !oomOnly)) {
17291                     Debug.getMemoryInfo(pid, mi);
17292                     hasSwapPss = mi.hasSwappedOutPss;
17293                 } else {
17294                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
17295                     mi.dalvikPrivateDirty = (int)tmpLong[0];
17296                 }
17297                 if (dumpDetails) {
17298                     if (localOnly) {
17299                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
17300                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
17301                         if (isCheckinRequest) {
17302                             pw.println();
17303                         }
17304                     } else {
17305                         pw.flush();
17306                         try {
17307                             TransferPipe tp = new TransferPipe();
17308                             try {
17309                                 thread.dumpMemInfo(tp.getWriteFd(),
17310                                         mi, isCheckinRequest, dumpFullDetails,
17311                                         dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
17312                                 tp.go(fd);
17313                             } finally {
17314                                 tp.kill();
17315                             }
17316                         } catch (IOException e) {
17317                             if (!isCheckinRequest) {
17318                                 pw.println("Got IoException! " + e);
17319                                 pw.flush();
17320                             }
17321                         } catch (RemoteException e) {
17322                             if (!isCheckinRequest) {
17323                                 pw.println("Got RemoteException! " + e);
17324                                 pw.flush();
17325                             }
17326                         }
17327                     }
17328                 }
17329
17330                 final long myTotalPss = mi.getTotalPss();
17331                 final long myTotalUss = mi.getTotalUss();
17332                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17333
17334                 synchronized (this) {
17335                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
17336                         // Record this for posterity if the process has been stable.
17337                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
17338                     }
17339                 }
17340
17341                 if (!isCheckinRequest && mi != null) {
17342                     totalPss += myTotalPss;
17343                     totalSwapPss += myTotalSwapPss;
17344                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
17345                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
17346                             myTotalSwapPss, pid, hasActivities);
17347                     procMems.add(pssItem);
17348                     procMemsMap.put(pid, pssItem);
17349
17350                     nativePss += mi.nativePss;
17351                     nativeSwapPss += mi.nativeSwappedOutPss;
17352                     dalvikPss += mi.dalvikPss;
17353                     dalvikSwapPss += mi.dalvikSwappedOutPss;
17354                     for (int j=0; j<dalvikSubitemPss.length; j++) {
17355                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17356                         dalvikSubitemSwapPss[j] +=
17357                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17358                     }
17359                     otherPss += mi.otherPss;
17360                     otherSwapPss += mi.otherSwappedOutPss;
17361                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17362                         long mem = mi.getOtherPss(j);
17363                         miscPss[j] += mem;
17364                         otherPss -= mem;
17365                         mem = mi.getOtherSwappedOutPss(j);
17366                         miscSwapPss[j] += mem;
17367                         otherSwapPss -= mem;
17368                     }
17369
17370                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17371                         cachedPss += myTotalPss;
17372                         cachedSwapPss += myTotalSwapPss;
17373                     }
17374
17375                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
17376                         if (oomIndex == (oomPss.length - 1)
17377                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
17378                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
17379                             oomPss[oomIndex] += myTotalPss;
17380                             oomSwapPss[oomIndex] += myTotalSwapPss;
17381                             if (oomProcs[oomIndex] == null) {
17382                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
17383                             }
17384                             oomProcs[oomIndex].add(pssItem);
17385                             break;
17386                         }
17387                     }
17388                 }
17389             }
17390         }
17391
17392         long nativeProcTotalPss = 0;
17393
17394         if (!isCheckinRequest && procs.size() > 1 && !packages) {
17395             // If we are showing aggregations, also look for native processes to
17396             // include so that our aggregations are more accurate.
17397             updateCpuStatsNow();
17398             mi = null;
17399             synchronized (mProcessCpuTracker) {
17400                 final int N = mProcessCpuTracker.countStats();
17401                 for (int i=0; i<N; i++) {
17402                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
17403                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
17404                         if (mi == null) {
17405                             mi = new Debug.MemoryInfo();
17406                         }
17407                         if (!brief && !oomOnly) {
17408                             Debug.getMemoryInfo(st.pid, mi);
17409                         } else {
17410                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
17411                             mi.nativePrivateDirty = (int)tmpLong[0];
17412                         }
17413
17414                         final long myTotalPss = mi.getTotalPss();
17415                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
17416                         totalPss += myTotalPss;
17417                         nativeProcTotalPss += myTotalPss;
17418
17419                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
17420                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
17421                         procMems.add(pssItem);
17422
17423                         nativePss += mi.nativePss;
17424                         nativeSwapPss += mi.nativeSwappedOutPss;
17425                         dalvikPss += mi.dalvikPss;
17426                         dalvikSwapPss += mi.dalvikSwappedOutPss;
17427                         for (int j=0; j<dalvikSubitemPss.length; j++) {
17428                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17429                             dalvikSubitemSwapPss[j] +=
17430                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
17431                         }
17432                         otherPss += mi.otherPss;
17433                         otherSwapPss += mi.otherSwappedOutPss;
17434                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17435                             long mem = mi.getOtherPss(j);
17436                             miscPss[j] += mem;
17437                             otherPss -= mem;
17438                             mem = mi.getOtherSwappedOutPss(j);
17439                             miscSwapPss[j] += mem;
17440                             otherSwapPss -= mem;
17441                         }
17442                         oomPss[0] += myTotalPss;
17443                         oomSwapPss[0] += myTotalSwapPss;
17444                         if (oomProcs[0] == null) {
17445                             oomProcs[0] = new ArrayList<MemItem>();
17446                         }
17447                         oomProcs[0].add(pssItem);
17448                     }
17449                 }
17450             }
17451
17452             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
17453
17454             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
17455             final int dalvikId = -2;
17456             catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, dalvikId));
17457             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
17458             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
17459                 String label = Debug.MemoryInfo.getOtherLabel(j);
17460                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
17461             }
17462             if (dalvikSubitemPss.length > 0) {
17463                 // Add dalvik subitems.
17464                 for (MemItem memItem : catMems) {
17465                     int memItemStart = 0, memItemEnd = 0;
17466                     if (memItem.id == dalvikId) {
17467                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_START;
17468                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_END;
17469                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DALVIK_OTHER) {
17470                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_START;
17471                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DALVIK_OTHER_END;
17472                     } else if (memItem.id == Debug.MemoryInfo.OTHER_DEX) {
17473                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_START;
17474                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_DEX_END;
17475                     } else if (memItem.id == Debug.MemoryInfo.OTHER_ART) {
17476                         memItemStart = Debug.MemoryInfo.OTHER_DVK_STAT_ART_START;
17477                         memItemEnd = Debug.MemoryInfo.OTHER_DVK_STAT_ART_END;
17478                     } else {
17479                         continue;  // No subitems, continue.
17480                     }
17481                     memItem.subitems = new ArrayList<MemItem>();
17482                     for (int j=memItemStart; j<=memItemEnd; j++) {
17483                         final String name = Debug.MemoryInfo.getOtherLabel(
17484                                 Debug.MemoryInfo.NUM_OTHER_STATS + j);
17485                         memItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
17486                                 dalvikSubitemSwapPss[j], j));
17487                     }
17488                 }
17489             }
17490
17491             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
17492             for (int j=0; j<oomPss.length; j++) {
17493                 if (oomPss[j] != 0) {
17494                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
17495                             : DUMP_MEM_OOM_LABEL[j];
17496                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
17497                             DUMP_MEM_OOM_ADJ[j]);
17498                     item.subitems = oomProcs[j];
17499                     oomMems.add(item);
17500                 }
17501             }
17502
17503             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
17504             if (!brief && !oomOnly && !isCompact) {
17505                 pw.println();
17506                 pw.println("Total PSS by process:");
17507                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
17508                 pw.println();
17509             }
17510             if (!isCompact) {
17511                 pw.println("Total PSS by OOM adjustment:");
17512             }
17513             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
17514             if (!brief && !oomOnly) {
17515                 PrintWriter out = categoryPw != null ? categoryPw : pw;
17516                 if (!isCompact) {
17517                     out.println();
17518                     out.println("Total PSS by category:");
17519                 }
17520                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
17521             }
17522             if (!isCompact) {
17523                 pw.println();
17524             }
17525             MemInfoReader memInfo = new MemInfoReader();
17526             memInfo.readMemInfo();
17527             if (nativeProcTotalPss > 0) {
17528                 synchronized (this) {
17529                     final long cachedKb = memInfo.getCachedSizeKb();
17530                     final long freeKb = memInfo.getFreeSizeKb();
17531                     final long zramKb = memInfo.getZramTotalSizeKb();
17532                     final long kernelKb = memInfo.getKernelUsedSizeKb();
17533                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
17534                             kernelKb*1024, nativeProcTotalPss*1024);
17535                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
17536                             nativeProcTotalPss);
17537                 }
17538             }
17539             if (!brief) {
17540                 if (!isCompact) {
17541                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
17542                     pw.print(" (status ");
17543                     switch (mLastMemoryLevel) {
17544                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
17545                             pw.println("normal)");
17546                             break;
17547                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
17548                             pw.println("moderate)");
17549                             break;
17550                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
17551                             pw.println("low)");
17552                             break;
17553                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17554                             pw.println("critical)");
17555                             break;
17556                         default:
17557                             pw.print(mLastMemoryLevel);
17558                             pw.println(")");
17559                             break;
17560                     }
17561                     pw.print(" Free RAM: ");
17562                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17563                             + memInfo.getFreeSizeKb()));
17564                     pw.print(" (");
17565                     pw.print(stringifyKBSize(cachedPss));
17566                     pw.print(" cached pss + ");
17567                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
17568                     pw.print(" cached kernel + ");
17569                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
17570                     pw.println(" free)");
17571                 } else {
17572                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
17573                     pw.print(cachedPss + memInfo.getCachedSizeKb()
17574                             + memInfo.getFreeSizeKb()); pw.print(",");
17575                     pw.println(totalPss - cachedPss);
17576                 }
17577             }
17578             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
17579                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17580                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
17581             if (!isCompact) {
17582                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
17583                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
17584                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
17585                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
17586                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
17587             } else {
17588                 pw.print("lostram,"); pw.println(lostRAM);
17589             }
17590             if (!brief) {
17591                 if (memInfo.getZramTotalSizeKb() != 0) {
17592                     if (!isCompact) {
17593                         pw.print("     ZRAM: ");
17594                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
17595                                 pw.print(" physical used for ");
17596                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
17597                                         - memInfo.getSwapFreeSizeKb()));
17598                                 pw.print(" in swap (");
17599                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
17600                                 pw.println(" total swap)");
17601                     } else {
17602                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
17603                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
17604                                 pw.println(memInfo.getSwapFreeSizeKb());
17605                     }
17606                 }
17607                 final long[] ksm = getKsmInfo();
17608                 if (!isCompact) {
17609                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17610                             || ksm[KSM_VOLATILE] != 0) {
17611                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
17612                                 pw.print(" saved from shared ");
17613                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
17614                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
17615                                 pw.print(" unshared; ");
17616                                 pw.print(stringifyKBSize(
17617                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
17618                     }
17619                     pw.print("   Tuning: ");
17620                     pw.print(ActivityManager.staticGetMemoryClass());
17621                     pw.print(" (large ");
17622                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17623                     pw.print("), oom ");
17624                     pw.print(stringifySize(
17625                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
17626                     pw.print(", restore limit ");
17627                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
17628                     if (ActivityManager.isLowRamDeviceStatic()) {
17629                         pw.print(" (low-ram)");
17630                     }
17631                     if (ActivityManager.isHighEndGfx()) {
17632                         pw.print(" (high-end-gfx)");
17633                     }
17634                     pw.println();
17635                 } else {
17636                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
17637                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
17638                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
17639                     pw.print("tuning,");
17640                     pw.print(ActivityManager.staticGetMemoryClass());
17641                     pw.print(',');
17642                     pw.print(ActivityManager.staticGetLargeMemoryClass());
17643                     pw.print(',');
17644                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
17645                     if (ActivityManager.isLowRamDeviceStatic()) {
17646                         pw.print(",low-ram");
17647                     }
17648                     if (ActivityManager.isHighEndGfx()) {
17649                         pw.print(",high-end-gfx");
17650                     }
17651                     pw.println();
17652                 }
17653             }
17654         }
17655     }
17656
17657     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
17658             long memtrack, String name) {
17659         sb.append("  ");
17660         sb.append(ProcessList.makeOomAdjString(oomAdj));
17661         sb.append(' ');
17662         sb.append(ProcessList.makeProcStateString(procState));
17663         sb.append(' ');
17664         ProcessList.appendRamKb(sb, pss);
17665         sb.append(": ");
17666         sb.append(name);
17667         if (memtrack > 0) {
17668             sb.append(" (");
17669             sb.append(stringifyKBSize(memtrack));
17670             sb.append(" memtrack)");
17671         }
17672     }
17673
17674     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
17675         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
17676         sb.append(" (pid ");
17677         sb.append(mi.pid);
17678         sb.append(") ");
17679         sb.append(mi.adjType);
17680         sb.append('\n');
17681         if (mi.adjReason != null) {
17682             sb.append("                      ");
17683             sb.append(mi.adjReason);
17684             sb.append('\n');
17685         }
17686     }
17687
17688     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
17689         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
17690         for (int i=0, N=memInfos.size(); i<N; i++) {
17691             ProcessMemInfo mi = memInfos.get(i);
17692             infoMap.put(mi.pid, mi);
17693         }
17694         updateCpuStatsNow();
17695         long[] memtrackTmp = new long[1];
17696         final List<ProcessCpuTracker.Stats> stats;
17697         // Get a list of Stats that have vsize > 0
17698         synchronized (mProcessCpuTracker) {
17699             stats = mProcessCpuTracker.getStats((st) -> {
17700                 return st.vsize > 0;
17701             });
17702         }
17703         final int statsCount = stats.size();
17704         for (int i = 0; i < statsCount; i++) {
17705             ProcessCpuTracker.Stats st = stats.get(i);
17706             long pss = Debug.getPss(st.pid, null, memtrackTmp);
17707             if (pss > 0) {
17708                 if (infoMap.indexOfKey(st.pid) < 0) {
17709                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
17710                             ProcessList.NATIVE_ADJ, -1, "native", null);
17711                     mi.pss = pss;
17712                     mi.memtrack = memtrackTmp[0];
17713                     memInfos.add(mi);
17714                 }
17715             }
17716         }
17717
17718         long totalPss = 0;
17719         long totalMemtrack = 0;
17720         for (int i=0, N=memInfos.size(); i<N; i++) {
17721             ProcessMemInfo mi = memInfos.get(i);
17722             if (mi.pss == 0) {
17723                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
17724                 mi.memtrack = memtrackTmp[0];
17725             }
17726             totalPss += mi.pss;
17727             totalMemtrack += mi.memtrack;
17728         }
17729         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
17730             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
17731                 if (lhs.oomAdj != rhs.oomAdj) {
17732                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
17733                 }
17734                 if (lhs.pss != rhs.pss) {
17735                     return lhs.pss < rhs.pss ? 1 : -1;
17736                 }
17737                 return 0;
17738             }
17739         });
17740
17741         StringBuilder tag = new StringBuilder(128);
17742         StringBuilder stack = new StringBuilder(128);
17743         tag.append("Low on memory -- ");
17744         appendMemBucket(tag, totalPss, "total", false);
17745         appendMemBucket(stack, totalPss, "total", true);
17746
17747         StringBuilder fullNativeBuilder = new StringBuilder(1024);
17748         StringBuilder shortNativeBuilder = new StringBuilder(1024);
17749         StringBuilder fullJavaBuilder = new StringBuilder(1024);
17750
17751         boolean firstLine = true;
17752         int lastOomAdj = Integer.MIN_VALUE;
17753         long extraNativeRam = 0;
17754         long extraNativeMemtrack = 0;
17755         long cachedPss = 0;
17756         for (int i=0, N=memInfos.size(); i<N; i++) {
17757             ProcessMemInfo mi = memInfos.get(i);
17758
17759             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
17760                 cachedPss += mi.pss;
17761             }
17762
17763             if (mi.oomAdj != ProcessList.NATIVE_ADJ
17764                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
17765                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
17766                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
17767                 if (lastOomAdj != mi.oomAdj) {
17768                     lastOomAdj = mi.oomAdj;
17769                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17770                         tag.append(" / ");
17771                     }
17772                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
17773                         if (firstLine) {
17774                             stack.append(":");
17775                             firstLine = false;
17776                         }
17777                         stack.append("\n\t at ");
17778                     } else {
17779                         stack.append("$");
17780                     }
17781                 } else {
17782                     tag.append(" ");
17783                     stack.append("$");
17784                 }
17785                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17786                     appendMemBucket(tag, mi.pss, mi.name, false);
17787                 }
17788                 appendMemBucket(stack, mi.pss, mi.name, true);
17789                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
17790                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
17791                     stack.append("(");
17792                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
17793                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
17794                             stack.append(DUMP_MEM_OOM_LABEL[k]);
17795                             stack.append(":");
17796                             stack.append(DUMP_MEM_OOM_ADJ[k]);
17797                         }
17798                     }
17799                     stack.append(")");
17800                 }
17801             }
17802
17803             appendMemInfo(fullNativeBuilder, mi);
17804             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
17805                 // The short form only has native processes that are >= 512K.
17806                 if (mi.pss >= 512) {
17807                     appendMemInfo(shortNativeBuilder, mi);
17808                 } else {
17809                     extraNativeRam += mi.pss;
17810                     extraNativeMemtrack += mi.memtrack;
17811                 }
17812             } else {
17813                 // Short form has all other details, but if we have collected RAM
17814                 // from smaller native processes let's dump a summary of that.
17815                 if (extraNativeRam > 0) {
17816                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
17817                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
17818                     shortNativeBuilder.append('\n');
17819                     extraNativeRam = 0;
17820                 }
17821                 appendMemInfo(fullJavaBuilder, mi);
17822             }
17823         }
17824
17825         fullJavaBuilder.append("           ");
17826         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
17827         fullJavaBuilder.append(": TOTAL");
17828         if (totalMemtrack > 0) {
17829             fullJavaBuilder.append(" (");
17830             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
17831             fullJavaBuilder.append(" memtrack)");
17832         } else {
17833         }
17834         fullJavaBuilder.append("\n");
17835
17836         MemInfoReader memInfo = new MemInfoReader();
17837         memInfo.readMemInfo();
17838         final long[] infos = memInfo.getRawInfo();
17839
17840         StringBuilder memInfoBuilder = new StringBuilder(1024);
17841         Debug.getMemInfo(infos);
17842         memInfoBuilder.append("  MemInfo: ");
17843         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
17844         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
17845         memInfoBuilder.append(stringifyKBSize(
17846                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
17847         memInfoBuilder.append(stringifyKBSize(
17848                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
17849         memInfoBuilder.append(stringifyKBSize(
17850                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
17851         memInfoBuilder.append("           ");
17852         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
17853         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
17854         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
17855         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
17856         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
17857             memInfoBuilder.append("  ZRAM: ");
17858             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
17859             memInfoBuilder.append(" RAM, ");
17860             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
17861             memInfoBuilder.append(" swap total, ");
17862             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
17863             memInfoBuilder.append(" swap free\n");
17864         }
17865         final long[] ksm = getKsmInfo();
17866         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
17867                 || ksm[KSM_VOLATILE] != 0) {
17868             memInfoBuilder.append("  KSM: ");
17869             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
17870             memInfoBuilder.append(" saved from shared ");
17871             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
17872             memInfoBuilder.append("\n       ");
17873             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
17874             memInfoBuilder.append(" unshared; ");
17875             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
17876             memInfoBuilder.append(" volatile\n");
17877         }
17878         memInfoBuilder.append("  Free RAM: ");
17879         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
17880                 + memInfo.getFreeSizeKb()));
17881         memInfoBuilder.append("\n");
17882         memInfoBuilder.append("  Used RAM: ");
17883         memInfoBuilder.append(stringifyKBSize(
17884                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
17885         memInfoBuilder.append("\n");
17886         memInfoBuilder.append("  Lost RAM: ");
17887         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
17888                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
17889                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
17890         memInfoBuilder.append("\n");
17891         Slog.i(TAG, "Low on memory:");
17892         Slog.i(TAG, shortNativeBuilder.toString());
17893         Slog.i(TAG, fullJavaBuilder.toString());
17894         Slog.i(TAG, memInfoBuilder.toString());
17895
17896         StringBuilder dropBuilder = new StringBuilder(1024);
17897         /*
17898         StringWriter oomSw = new StringWriter();
17899         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
17900         StringWriter catSw = new StringWriter();
17901         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17902         String[] emptyArgs = new String[] { };
17903         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
17904         oomPw.flush();
17905         String oomString = oomSw.toString();
17906         */
17907         dropBuilder.append("Low on memory:");
17908         dropBuilder.append(stack);
17909         dropBuilder.append('\n');
17910         dropBuilder.append(fullNativeBuilder);
17911         dropBuilder.append(fullJavaBuilder);
17912         dropBuilder.append('\n');
17913         dropBuilder.append(memInfoBuilder);
17914         dropBuilder.append('\n');
17915         /*
17916         dropBuilder.append(oomString);
17917         dropBuilder.append('\n');
17918         */
17919         StringWriter catSw = new StringWriter();
17920         synchronized (ActivityManagerService.this) {
17921             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
17922             String[] emptyArgs = new String[] { };
17923             catPw.println();
17924             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
17925             catPw.println();
17926             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
17927                     false, null).dumpLocked();
17928             catPw.println();
17929             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
17930             catPw.flush();
17931         }
17932         dropBuilder.append(catSw.toString());
17933         addErrorToDropBox("lowmem", null, "system_server", null,
17934                 null, tag.toString(), dropBuilder.toString(), null, null);
17935         //Slog.i(TAG, "Sent to dropbox:");
17936         //Slog.i(TAG, dropBuilder.toString());
17937         synchronized (ActivityManagerService.this) {
17938             long now = SystemClock.uptimeMillis();
17939             if (mLastMemUsageReportTime < now) {
17940                 mLastMemUsageReportTime = now;
17941             }
17942         }
17943     }
17944
17945     /**
17946      * Searches array of arguments for the specified string
17947      * @param args array of argument strings
17948      * @param value value to search for
17949      * @return true if the value is contained in the array
17950      */
17951     private static boolean scanArgs(String[] args, String value) {
17952         if (args != null) {
17953             for (String arg : args) {
17954                 if (value.equals(arg)) {
17955                     return true;
17956                 }
17957             }
17958         }
17959         return false;
17960     }
17961
17962     private final boolean removeDyingProviderLocked(ProcessRecord proc,
17963             ContentProviderRecord cpr, boolean always) {
17964         final boolean inLaunching = mLaunchingProviders.contains(cpr);
17965
17966         if (!inLaunching || always) {
17967             synchronized (cpr) {
17968                 cpr.launchingApp = null;
17969                 cpr.notifyAll();
17970             }
17971             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
17972             String names[] = cpr.info.authority.split(";");
17973             for (int j = 0; j < names.length; j++) {
17974                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
17975             }
17976         }
17977
17978         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
17979             ContentProviderConnection conn = cpr.connections.get(i);
17980             if (conn.waiting) {
17981                 // If this connection is waiting for the provider, then we don't
17982                 // need to mess with its process unless we are always removing
17983                 // or for some reason the provider is not currently launching.
17984                 if (inLaunching && !always) {
17985                     continue;
17986                 }
17987             }
17988             ProcessRecord capp = conn.client;
17989             conn.dead = true;
17990             if (conn.stableCount > 0) {
17991                 if (!capp.persistent && capp.thread != null
17992                         && capp.pid != 0
17993                         && capp.pid != MY_PID) {
17994                     capp.kill("depends on provider "
17995                             + cpr.name.flattenToShortString()
17996                             + " in dying proc " + (proc != null ? proc.processName : "??")
17997                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
17998                 }
17999             } else if (capp.thread != null && conn.provider.provider != null) {
18000                 try {
18001                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
18002                 } catch (RemoteException e) {
18003                 }
18004                 // In the protocol here, we don't expect the client to correctly
18005                 // clean up this connection, we'll just remove it.
18006                 cpr.connections.remove(i);
18007                 if (conn.client.conProviders.remove(conn)) {
18008                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
18009                 }
18010             }
18011         }
18012
18013         if (inLaunching && always) {
18014             mLaunchingProviders.remove(cpr);
18015         }
18016         return inLaunching;
18017     }
18018
18019     /**
18020      * Main code for cleaning up a process when it has gone away.  This is
18021      * called both as a result of the process dying, or directly when stopping
18022      * a process when running in single process mode.
18023      *
18024      * @return Returns true if the given process has been restarted, so the
18025      * app that was passed in must remain on the process lists.
18026      */
18027     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
18028             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
18029         if (index >= 0) {
18030             removeLruProcessLocked(app);
18031             ProcessList.remove(app.pid);
18032         }
18033
18034         mProcessesToGc.remove(app);
18035         mPendingPssProcesses.remove(app);
18036
18037         // Dismiss any open dialogs.
18038         if (app.crashDialog != null && !app.forceCrashReport) {
18039             app.crashDialog.dismiss();
18040             app.crashDialog = null;
18041         }
18042         if (app.anrDialog != null) {
18043             app.anrDialog.dismiss();
18044             app.anrDialog = null;
18045         }
18046         if (app.waitDialog != null) {
18047             app.waitDialog.dismiss();
18048             app.waitDialog = null;
18049         }
18050
18051         app.crashing = false;
18052         app.notResponding = false;
18053
18054         app.resetPackageList(mProcessStats);
18055         app.unlinkDeathRecipient();
18056         app.makeInactive(mProcessStats);
18057         app.waitingToKill = null;
18058         app.forcingToImportant = null;
18059         updateProcessForegroundLocked(app, false, false);
18060         app.foregroundActivities = false;
18061         app.hasShownUi = false;
18062         app.treatLikeActivity = false;
18063         app.hasAboveClient = false;
18064         app.hasClientActivities = false;
18065
18066         mServices.killServicesLocked(app, allowRestart);
18067
18068         boolean restart = false;
18069
18070         // Remove published content providers.
18071         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
18072             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
18073             final boolean always = app.bad || !allowRestart;
18074             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
18075             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
18076                 // We left the provider in the launching list, need to
18077                 // restart it.
18078                 restart = true;
18079             }
18080
18081             cpr.provider = null;
18082             cpr.proc = null;
18083         }
18084         app.pubProviders.clear();
18085
18086         // Take care of any launching providers waiting for this process.
18087         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
18088             restart = true;
18089         }
18090
18091         // Unregister from connected content providers.
18092         if (!app.conProviders.isEmpty()) {
18093             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
18094                 ContentProviderConnection conn = app.conProviders.get(i);
18095                 conn.provider.connections.remove(conn);
18096                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
18097                         conn.provider.name);
18098             }
18099             app.conProviders.clear();
18100         }
18101
18102         // At this point there may be remaining entries in mLaunchingProviders
18103         // where we were the only one waiting, so they are no longer of use.
18104         // Look for these and clean up if found.
18105         // XXX Commented out for now.  Trying to figure out a way to reproduce
18106         // the actual situation to identify what is actually going on.
18107         if (false) {
18108             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18109                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
18110                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
18111                     synchronized (cpr) {
18112                         cpr.launchingApp = null;
18113                         cpr.notifyAll();
18114                     }
18115                 }
18116             }
18117         }
18118
18119         skipCurrentReceiverLocked(app);
18120
18121         // Unregister any receivers.
18122         for (int i = app.receivers.size() - 1; i >= 0; i--) {
18123             removeReceiverLocked(app.receivers.valueAt(i));
18124         }
18125         app.receivers.clear();
18126
18127         // If the app is undergoing backup, tell the backup manager about it
18128         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
18129             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
18130                     + mBackupTarget.appInfo + " died during backup");
18131             mHandler.post(new Runnable() {
18132                 @Override
18133                 public void run(){
18134                     try {
18135                         IBackupManager bm = IBackupManager.Stub.asInterface(
18136                                 ServiceManager.getService(Context.BACKUP_SERVICE));
18137                         bm.agentDisconnected(app.info.packageName);
18138                     } catch (RemoteException e) {
18139                         // can't happen; backup manager is local
18140                     }
18141                 }
18142             });
18143         }
18144
18145         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
18146             ProcessChangeItem item = mPendingProcessChanges.get(i);
18147             if (item.pid == app.pid) {
18148                 mPendingProcessChanges.remove(i);
18149                 mAvailProcessChanges.add(item);
18150             }
18151         }
18152         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
18153                 null).sendToTarget();
18154
18155         // If the caller is restarting this app, then leave it in its
18156         // current lists and let the caller take care of it.
18157         if (restarting) {
18158             return false;
18159         }
18160
18161         if (!app.persistent || app.isolated) {
18162             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
18163                     "Removing non-persistent process during cleanup: " + app);
18164             if (!replacingPid) {
18165                 removeProcessNameLocked(app.processName, app.uid, app);
18166             }
18167             if (mHeavyWeightProcess == app) {
18168                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
18169                         mHeavyWeightProcess.userId, 0));
18170                 mHeavyWeightProcess = null;
18171             }
18172         } else if (!app.removed) {
18173             // This app is persistent, so we need to keep its record around.
18174             // If it is not already on the pending app list, add it there
18175             // and start a new process for it.
18176             if (mPersistentStartingProcesses.indexOf(app) < 0) {
18177                 mPersistentStartingProcesses.add(app);
18178                 restart = true;
18179             }
18180         }
18181         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
18182                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
18183         mProcessesOnHold.remove(app);
18184
18185         if (app == mHomeProcess) {
18186             mHomeProcess = null;
18187         }
18188         if (app == mPreviousProcess) {
18189             mPreviousProcess = null;
18190         }
18191
18192         if (restart && !app.isolated) {
18193             // We have components that still need to be running in the
18194             // process, so re-launch it.
18195             if (index < 0) {
18196                 ProcessList.remove(app.pid);
18197             }
18198             addProcessNameLocked(app);
18199             startProcessLocked(app, "restart", app.processName);
18200             return true;
18201         } else if (app.pid > 0 && app.pid != MY_PID) {
18202             // Goodbye!
18203             boolean removed;
18204             synchronized (mPidsSelfLocked) {
18205                 mPidsSelfLocked.remove(app.pid);
18206                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
18207             }
18208             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
18209             if (app.isolated) {
18210                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
18211             }
18212             app.setPid(0);
18213         }
18214         return false;
18215     }
18216
18217     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
18218         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18219             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18220             if (cpr.launchingApp == app) {
18221                 return true;
18222             }
18223         }
18224         return false;
18225     }
18226
18227     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
18228         // Look through the content providers we are waiting to have launched,
18229         // and if any run in this process then either schedule a restart of
18230         // the process or kill the client waiting for it if this process has
18231         // gone bad.
18232         boolean restart = false;
18233         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
18234             ContentProviderRecord cpr = mLaunchingProviders.get(i);
18235             if (cpr.launchingApp == app) {
18236                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
18237                     restart = true;
18238                 } else {
18239                     removeDyingProviderLocked(app, cpr, true);
18240                 }
18241             }
18242         }
18243         return restart;
18244     }
18245
18246     // =========================================================
18247     // SERVICES
18248     // =========================================================
18249
18250     @Override
18251     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
18252             int flags) {
18253         enforceNotIsolatedCaller("getServices");
18254
18255         final int callingUid = Binder.getCallingUid();
18256         final boolean canInteractAcrossUsers = (ActivityManager.checkUidPermission(
18257             INTERACT_ACROSS_USERS_FULL, callingUid) == PERMISSION_GRANTED);
18258         final boolean allowed = isGetTasksAllowed("getServices", Binder.getCallingPid(),
18259             callingUid);
18260         synchronized (this) {
18261             return mServices.getRunningServiceInfoLocked(maxNum, flags, callingUid,
18262                 allowed, canInteractAcrossUsers);
18263         }
18264     }
18265
18266     @Override
18267     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
18268         enforceNotIsolatedCaller("getRunningServiceControlPanel");
18269         synchronized (this) {
18270             return mServices.getRunningServiceControlPanelLocked(name);
18271         }
18272     }
18273
18274     @Override
18275     public ComponentName startService(IApplicationThread caller, Intent service,
18276             String resolvedType, boolean requireForeground, String callingPackage, int userId)
18277             throws TransactionTooLargeException {
18278         enforceNotIsolatedCaller("startService");
18279         // Refuse possible leaked file descriptors
18280         if (service != null && service.hasFileDescriptors() == true) {
18281             throw new IllegalArgumentException("File descriptors passed in Intent");
18282         }
18283
18284         if (callingPackage == null) {
18285             throw new IllegalArgumentException("callingPackage cannot be null");
18286         }
18287
18288         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18289                 "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
18290         synchronized(this) {
18291             final int callingPid = Binder.getCallingPid();
18292             final int callingUid = Binder.getCallingUid();
18293             final long origId = Binder.clearCallingIdentity();
18294             ComponentName res;
18295             try {
18296                 res = mServices.startServiceLocked(caller, service,
18297                         resolvedType, callingPid, callingUid,
18298                         requireForeground, callingPackage, userId);
18299             } finally {
18300                 Binder.restoreCallingIdentity(origId);
18301             }
18302             return res;
18303         }
18304     }
18305
18306     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
18307             boolean fgRequired, String callingPackage, int userId)
18308             throws TransactionTooLargeException {
18309         synchronized(this) {
18310             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
18311                     "startServiceInPackage: " + service + " type=" + resolvedType);
18312             final long origId = Binder.clearCallingIdentity();
18313             ComponentName res;
18314             try {
18315                 res = mServices.startServiceLocked(null, service,
18316                         resolvedType, -1, uid, fgRequired, callingPackage, userId);
18317             } finally {
18318                 Binder.restoreCallingIdentity(origId);
18319             }
18320             return res;
18321         }
18322     }
18323
18324     @Override
18325     public int stopService(IApplicationThread caller, Intent service,
18326             String resolvedType, int userId) {
18327         enforceNotIsolatedCaller("stopService");
18328         // Refuse possible leaked file descriptors
18329         if (service != null && service.hasFileDescriptors() == true) {
18330             throw new IllegalArgumentException("File descriptors passed in Intent");
18331         }
18332
18333         synchronized(this) {
18334             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
18335         }
18336     }
18337
18338     @Override
18339     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
18340         enforceNotIsolatedCaller("peekService");
18341         // Refuse possible leaked file descriptors
18342         if (service != null && service.hasFileDescriptors() == true) {
18343             throw new IllegalArgumentException("File descriptors passed in Intent");
18344         }
18345
18346         if (callingPackage == null) {
18347             throw new IllegalArgumentException("callingPackage cannot be null");
18348         }
18349
18350         synchronized(this) {
18351             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
18352         }
18353     }
18354
18355     @Override
18356     public boolean stopServiceToken(ComponentName className, IBinder token,
18357             int startId) {
18358         synchronized(this) {
18359             return mServices.stopServiceTokenLocked(className, token, startId);
18360         }
18361     }
18362
18363     @Override
18364     public void setServiceForeground(ComponentName className, IBinder token,
18365             int id, Notification notification, int flags) {
18366         synchronized(this) {
18367             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
18368         }
18369     }
18370
18371     @Override
18372     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
18373             boolean requireFull, String name, String callerPackage) {
18374         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
18375                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
18376     }
18377
18378     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
18379             String className, int flags) {
18380         boolean result = false;
18381         // For apps that don't have pre-defined UIDs, check for permission
18382         if (UserHandle.getAppId(aInfo.uid) >= FIRST_APPLICATION_UID) {
18383             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18384                 if (ActivityManager.checkUidPermission(
18385                         INTERACT_ACROSS_USERS,
18386                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
18387                     ComponentName comp = new ComponentName(aInfo.packageName, className);
18388                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
18389                             + " requests FLAG_SINGLE_USER, but app does not hold "
18390                             + INTERACT_ACROSS_USERS;
18391                     Slog.w(TAG, msg);
18392                     throw new SecurityException(msg);
18393                 }
18394                 // Permission passed
18395                 result = true;
18396             }
18397         } else if ("system".equals(componentProcessName)) {
18398             result = true;
18399         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
18400             // Phone app and persistent apps are allowed to export singleuser providers.
18401             result = UserHandle.isSameApp(aInfo.uid, PHONE_UID)
18402                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
18403         }
18404         if (DEBUG_MU) Slog.v(TAG_MU,
18405                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
18406                 + Integer.toHexString(flags) + ") = " + result);
18407         return result;
18408     }
18409
18410     /**
18411      * Checks to see if the caller is in the same app as the singleton
18412      * component, or the component is in a special app. It allows special apps
18413      * to export singleton components but prevents exporting singleton
18414      * components for regular apps.
18415      */
18416     boolean isValidSingletonCall(int callingUid, int componentUid) {
18417         int componentAppId = UserHandle.getAppId(componentUid);
18418         return UserHandle.isSameApp(callingUid, componentUid)
18419                 || componentAppId == SYSTEM_UID
18420                 || componentAppId == PHONE_UID
18421                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
18422                         == PackageManager.PERMISSION_GRANTED;
18423     }
18424
18425     public int bindService(IApplicationThread caller, IBinder token, Intent service,
18426             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18427             int userId) throws TransactionTooLargeException {
18428         enforceNotIsolatedCaller("bindService");
18429
18430         // Refuse possible leaked file descriptors
18431         if (service != null && service.hasFileDescriptors() == true) {
18432             throw new IllegalArgumentException("File descriptors passed in Intent");
18433         }
18434
18435         if (callingPackage == null) {
18436             throw new IllegalArgumentException("callingPackage cannot be null");
18437         }
18438
18439         synchronized(this) {
18440             return mServices.bindServiceLocked(caller, token, service,
18441                     resolvedType, connection, flags, callingPackage, userId);
18442         }
18443     }
18444
18445     public boolean unbindService(IServiceConnection connection) {
18446         synchronized (this) {
18447             return mServices.unbindServiceLocked(connection);
18448         }
18449     }
18450
18451     public void publishService(IBinder token, Intent intent, IBinder service) {
18452         // Refuse possible leaked file descriptors
18453         if (intent != null && intent.hasFileDescriptors() == true) {
18454             throw new IllegalArgumentException("File descriptors passed in Intent");
18455         }
18456
18457         synchronized(this) {
18458             if (!(token instanceof ServiceRecord)) {
18459                 throw new IllegalArgumentException("Invalid service token");
18460             }
18461             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
18462         }
18463     }
18464
18465     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
18466         // Refuse possible leaked file descriptors
18467         if (intent != null && intent.hasFileDescriptors() == true) {
18468             throw new IllegalArgumentException("File descriptors passed in Intent");
18469         }
18470
18471         synchronized(this) {
18472             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
18473         }
18474     }
18475
18476     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
18477         synchronized(this) {
18478             if (!(token instanceof ServiceRecord)) {
18479                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
18480                 throw new IllegalArgumentException("Invalid service token");
18481             }
18482             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
18483         }
18484     }
18485
18486     // =========================================================
18487     // BACKUP AND RESTORE
18488     // =========================================================
18489
18490     // Cause the target app to be launched if necessary and its backup agent
18491     // instantiated.  The backup agent will invoke backupAgentCreated() on the
18492     // activity manager to announce its creation.
18493     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
18494         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
18495         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
18496
18497         IPackageManager pm = AppGlobals.getPackageManager();
18498         ApplicationInfo app = null;
18499         try {
18500             app = pm.getApplicationInfo(packageName, 0, userId);
18501         } catch (RemoteException e) {
18502             // can't happen; package manager is process-local
18503         }
18504         if (app == null) {
18505             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
18506             return false;
18507         }
18508
18509         int oldBackupUid;
18510         int newBackupUid;
18511
18512         synchronized(this) {
18513             // !!! TODO: currently no check here that we're already bound
18514             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
18515             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18516             synchronized (stats) {
18517                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
18518             }
18519
18520             // Backup agent is now in use, its package can't be stopped.
18521             try {
18522                 AppGlobals.getPackageManager().setPackageStoppedState(
18523                         app.packageName, false, UserHandle.getUserId(app.uid));
18524             } catch (RemoteException e) {
18525             } catch (IllegalArgumentException e) {
18526                 Slog.w(TAG, "Failed trying to unstop package "
18527                         + app.packageName + ": " + e);
18528             }
18529
18530             BackupRecord r = new BackupRecord(ss, app, backupMode);
18531             ComponentName hostingName =
18532                     (backupMode == ApplicationThreadConstants.BACKUP_MODE_INCREMENTAL)
18533                             ? new ComponentName(app.packageName, app.backupAgentName)
18534                             : new ComponentName("android", "FullBackupAgent");
18535             // startProcessLocked() returns existing proc's record if it's already running
18536             ProcessRecord proc = startProcessLocked(app.processName, app,
18537                     false, 0, "backup", hostingName, false, false, false);
18538             if (proc == null) {
18539                 Slog.e(TAG, "Unable to start backup agent process " + r);
18540                 return false;
18541             }
18542
18543             // If the app is a regular app (uid >= 10000) and not the system server or phone
18544             // process, etc, then mark it as being in full backup so that certain calls to the
18545             // process can be blocked. This is not reset to false anywhere because we kill the
18546             // process after the full backup is done and the ProcessRecord will vaporize anyway.
18547             if (UserHandle.isApp(app.uid) &&
18548                     backupMode == ApplicationThreadConstants.BACKUP_MODE_FULL) {
18549                 proc.inFullBackup = true;
18550             }
18551             r.app = proc;
18552             oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18553             newBackupUid = proc.inFullBackup ? r.appInfo.uid : -1;
18554             mBackupTarget = r;
18555             mBackupAppName = app.packageName;
18556
18557             // Try not to kill the process during backup
18558             updateOomAdjLocked(proc, true);
18559
18560             // If the process is already attached, schedule the creation of the backup agent now.
18561             // If it is not yet live, this will be done when it attaches to the framework.
18562             if (proc.thread != null) {
18563                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
18564                 try {
18565                     proc.thread.scheduleCreateBackupAgent(app,
18566                             compatibilityInfoForPackageLocked(app), backupMode);
18567                 } catch (RemoteException e) {
18568                     // Will time out on the backup manager side
18569                 }
18570             } else {
18571                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
18572             }
18573             // Invariants: at this point, the target app process exists and the application
18574             // is either already running or in the process of coming up.  mBackupTarget and
18575             // mBackupAppName describe the app, so that when it binds back to the AM we
18576             // know that it's scheduled for a backup-agent operation.
18577         }
18578
18579         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18580         if (oldBackupUid != -1) {
18581             js.removeBackingUpUid(oldBackupUid);
18582         }
18583         if (newBackupUid != -1) {
18584             js.addBackingUpUid(newBackupUid);
18585         }
18586
18587         return true;
18588     }
18589
18590     @Override
18591     public void clearPendingBackup() {
18592         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
18593         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
18594
18595         synchronized (this) {
18596             mBackupTarget = null;
18597             mBackupAppName = null;
18598         }
18599
18600         JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18601         js.clearAllBackingUpUids();
18602     }
18603
18604     // A backup agent has just come up
18605     public void backupAgentCreated(String agentPackageName, IBinder agent) {
18606         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
18607                 + " = " + agent);
18608
18609         synchronized(this) {
18610             if (!agentPackageName.equals(mBackupAppName)) {
18611                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
18612                 return;
18613             }
18614         }
18615
18616         long oldIdent = Binder.clearCallingIdentity();
18617         try {
18618             IBackupManager bm = IBackupManager.Stub.asInterface(
18619                     ServiceManager.getService(Context.BACKUP_SERVICE));
18620             bm.agentConnected(agentPackageName, agent);
18621         } catch (RemoteException e) {
18622             // can't happen; the backup manager service is local
18623         } catch (Exception e) {
18624             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
18625             e.printStackTrace();
18626         } finally {
18627             Binder.restoreCallingIdentity(oldIdent);
18628         }
18629     }
18630
18631     // done with this agent
18632     public void unbindBackupAgent(ApplicationInfo appInfo) {
18633         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
18634         if (appInfo == null) {
18635             Slog.w(TAG, "unbind backup agent for null app");
18636             return;
18637         }
18638
18639         int oldBackupUid;
18640
18641         synchronized(this) {
18642             try {
18643                 if (mBackupAppName == null) {
18644                     Slog.w(TAG, "Unbinding backup agent with no active backup");
18645                     return;
18646                 }
18647
18648                 if (!mBackupAppName.equals(appInfo.packageName)) {
18649                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
18650                     return;
18651                 }
18652
18653                 // Not backing this app up any more; reset its OOM adjustment
18654                 final ProcessRecord proc = mBackupTarget.app;
18655                 updateOomAdjLocked(proc, true);
18656                 proc.inFullBackup = false;
18657
18658                 oldBackupUid = mBackupTarget != null ? mBackupTarget.appInfo.uid : -1;
18659
18660                 // If the app crashed during backup, 'thread' will be null here
18661                 if (proc.thread != null) {
18662                     try {
18663                         proc.thread.scheduleDestroyBackupAgent(appInfo,
18664                                 compatibilityInfoForPackageLocked(appInfo));
18665                     } catch (Exception e) {
18666                         Slog.e(TAG, "Exception when unbinding backup agent:");
18667                         e.printStackTrace();
18668                     }
18669                 }
18670             } finally {
18671                 mBackupTarget = null;
18672                 mBackupAppName = null;
18673             }
18674         }
18675
18676         if (oldBackupUid != -1) {
18677             JobSchedulerInternal js = LocalServices.getService(JobSchedulerInternal.class);
18678             js.removeBackingUpUid(oldBackupUid);
18679         }
18680     }
18681
18682     // =========================================================
18683     // BROADCASTS
18684     // =========================================================
18685
18686     private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
18687         if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
18688             return false;
18689         }
18690         // Easy case -- we have the app's ProcessRecord.
18691         if (record != null) {
18692             return record.info.isInstantApp();
18693         }
18694         // Otherwise check with PackageManager.
18695         if (callerPackage == null) {
18696             Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
18697             throw new IllegalArgumentException("Calling application did not provide package name");
18698         }
18699         mAppOpsService.checkPackage(uid, callerPackage);
18700         try {
18701             IPackageManager pm = AppGlobals.getPackageManager();
18702             return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
18703         } catch (RemoteException e) {
18704             Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
18705             return true;
18706         }
18707     }
18708
18709     boolean isPendingBroadcastProcessLocked(int pid) {
18710         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
18711                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
18712     }
18713
18714     void skipPendingBroadcastLocked(int pid) {
18715             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
18716             for (BroadcastQueue queue : mBroadcastQueues) {
18717                 queue.skipPendingBroadcastLocked(pid);
18718             }
18719     }
18720
18721     // The app just attached; send any pending broadcasts that it should receive
18722     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
18723         boolean didSomething = false;
18724         for (BroadcastQueue queue : mBroadcastQueues) {
18725             didSomething |= queue.sendPendingBroadcastsLocked(app);
18726         }
18727         return didSomething;
18728     }
18729
18730     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
18731             IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
18732             int flags) {
18733         enforceNotIsolatedCaller("registerReceiver");
18734         ArrayList<Intent> stickyIntents = null;
18735         ProcessRecord callerApp = null;
18736         final boolean visibleToInstantApps
18737                 = (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) != 0;
18738         int callingUid;
18739         int callingPid;
18740         boolean instantApp;
18741         synchronized(this) {
18742             if (caller != null) {
18743                 callerApp = getRecordForAppLocked(caller);
18744                 if (callerApp == null) {
18745                     throw new SecurityException(
18746                             "Unable to find app for caller " + caller
18747                             + " (pid=" + Binder.getCallingPid()
18748                             + ") when registering receiver " + receiver);
18749                 }
18750                 if (callerApp.info.uid != SYSTEM_UID &&
18751                         !callerApp.pkgList.containsKey(callerPackage) &&
18752                         !"android".equals(callerPackage)) {
18753                     throw new SecurityException("Given caller package " + callerPackage
18754                             + " is not running in process " + callerApp);
18755                 }
18756                 callingUid = callerApp.info.uid;
18757                 callingPid = callerApp.pid;
18758             } else {
18759                 callerPackage = null;
18760                 callingUid = Binder.getCallingUid();
18761                 callingPid = Binder.getCallingPid();
18762             }
18763
18764             instantApp = isInstantApp(callerApp, callerPackage, callingUid);
18765             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
18766                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
18767
18768             Iterator<String> actions = filter.actionsIterator();
18769             if (actions == null) {
18770                 ArrayList<String> noAction = new ArrayList<String>(1);
18771                 noAction.add(null);
18772                 actions = noAction.iterator();
18773             }
18774
18775             // Collect stickies of users
18776             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
18777             while (actions.hasNext()) {
18778                 String action = actions.next();
18779                 for (int id : userIds) {
18780                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
18781                     if (stickies != null) {
18782                         ArrayList<Intent> intents = stickies.get(action);
18783                         if (intents != null) {
18784                             if (stickyIntents == null) {
18785                                 stickyIntents = new ArrayList<Intent>();
18786                             }
18787                             stickyIntents.addAll(intents);
18788                         }
18789                     }
18790                 }
18791             }
18792         }
18793
18794         ArrayList<Intent> allSticky = null;
18795         if (stickyIntents != null) {
18796             final ContentResolver resolver = mContext.getContentResolver();
18797             // Look for any matching sticky broadcasts...
18798             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
18799                 Intent intent = stickyIntents.get(i);
18800                 // Don't provided intents that aren't available to instant apps.
18801                 if (instantApp &&
18802                         (intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) == 0) {
18803                     continue;
18804                 }
18805                 // If intent has scheme "content", it will need to acccess
18806                 // provider that needs to lock mProviderMap in ActivityThread
18807                 // and also it may need to wait application response, so we
18808                 // cannot lock ActivityManagerService here.
18809                 if (filter.match(resolver, intent, true, TAG) >= 0) {
18810                     if (allSticky == null) {
18811                         allSticky = new ArrayList<Intent>();
18812                     }
18813                     allSticky.add(intent);
18814                 }
18815             }
18816         }
18817
18818         // The first sticky in the list is returned directly back to the client.
18819         Intent sticky = allSticky != null ? allSticky.get(0) : null;
18820         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
18821         if (receiver == null) {
18822             return sticky;
18823         }
18824
18825         synchronized (this) {
18826             if (callerApp != null && (callerApp.thread == null
18827                     || callerApp.thread.asBinder() != caller.asBinder())) {
18828                 // Original caller already died
18829                 return null;
18830             }
18831             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18832             if (rl == null) {
18833                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
18834                         userId, receiver);
18835                 if (rl.app != null) {
18836                     rl.app.receivers.add(rl);
18837                 } else {
18838                     try {
18839                         receiver.asBinder().linkToDeath(rl, 0);
18840                     } catch (RemoteException e) {
18841                         return sticky;
18842                     }
18843                     rl.linkedToDeath = true;
18844                 }
18845                 mRegisteredReceivers.put(receiver.asBinder(), rl);
18846             } else if (rl.uid != callingUid) {
18847                 throw new IllegalArgumentException(
18848                         "Receiver requested to register for uid " + callingUid
18849                         + " was previously registered for uid " + rl.uid
18850                         + " callerPackage is " + callerPackage);
18851             } else if (rl.pid != callingPid) {
18852                 throw new IllegalArgumentException(
18853                         "Receiver requested to register for pid " + callingPid
18854                         + " was previously registered for pid " + rl.pid
18855                         + " callerPackage is " + callerPackage);
18856             } else if (rl.userId != userId) {
18857                 throw new IllegalArgumentException(
18858                         "Receiver requested to register for user " + userId
18859                         + " was previously registered for user " + rl.userId
18860                         + " callerPackage is " + callerPackage);
18861             }
18862             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
18863                     permission, callingUid, userId, instantApp, visibleToInstantApps);
18864             rl.add(bf);
18865             if (!bf.debugCheck()) {
18866                 Slog.w(TAG, "==> For Dynamic broadcast");
18867             }
18868             mReceiverResolver.addFilter(bf);
18869
18870             // Enqueue broadcasts for all existing stickies that match
18871             // this filter.
18872             if (allSticky != null) {
18873                 ArrayList receivers = new ArrayList();
18874                 receivers.add(bf);
18875
18876                 final int stickyCount = allSticky.size();
18877                 for (int i = 0; i < stickyCount; i++) {
18878                     Intent intent = allSticky.get(i);
18879                     BroadcastQueue queue = broadcastQueueForIntent(intent);
18880                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
18881                             null, -1, -1, false, null, null, AppOpsManager.OP_NONE, null, receivers,
18882                             null, 0, null, null, false, true, true, -1);
18883                     queue.enqueueParallelBroadcastLocked(r);
18884                     queue.scheduleBroadcastsLocked();
18885                 }
18886             }
18887
18888             return sticky;
18889         }
18890     }
18891
18892     public void unregisterReceiver(IIntentReceiver receiver) {
18893         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
18894
18895         final long origId = Binder.clearCallingIdentity();
18896         try {
18897             boolean doTrim = false;
18898
18899             synchronized(this) {
18900                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
18901                 if (rl != null) {
18902                     final BroadcastRecord r = rl.curBroadcast;
18903                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
18904                         final boolean doNext = r.queue.finishReceiverLocked(
18905                                 r, r.resultCode, r.resultData, r.resultExtras,
18906                                 r.resultAbort, false);
18907                         if (doNext) {
18908                             doTrim = true;
18909                             r.queue.processNextBroadcast(false);
18910                         }
18911                     }
18912
18913                     if (rl.app != null) {
18914                         rl.app.receivers.remove(rl);
18915                     }
18916                     removeReceiverLocked(rl);
18917                     if (rl.linkedToDeath) {
18918                         rl.linkedToDeath = false;
18919                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
18920                     }
18921                 }
18922             }
18923
18924             // If we actually concluded any broadcasts, we might now be able
18925             // to trim the recipients' apps from our working set
18926             if (doTrim) {
18927                 trimApplications();
18928                 return;
18929             }
18930
18931         } finally {
18932             Binder.restoreCallingIdentity(origId);
18933         }
18934     }
18935
18936     void removeReceiverLocked(ReceiverList rl) {
18937         mRegisteredReceivers.remove(rl.receiver.asBinder());
18938         for (int i = rl.size() - 1; i >= 0; i--) {
18939             mReceiverResolver.removeFilter(rl.get(i));
18940         }
18941     }
18942
18943     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
18944         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18945             ProcessRecord r = mLruProcesses.get(i);
18946             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
18947                 try {
18948                     r.thread.dispatchPackageBroadcast(cmd, packages);
18949                 } catch (RemoteException ex) {
18950                 }
18951             }
18952         }
18953     }
18954
18955     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
18956             int callingUid, int[] users) {
18957         // TODO: come back and remove this assumption to triage all broadcasts
18958         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
18959
18960         List<ResolveInfo> receivers = null;
18961         try {
18962             HashSet<ComponentName> singleUserReceivers = null;
18963             boolean scannedFirstReceivers = false;
18964             for (int user : users) {
18965                 // Skip users that have Shell restrictions, with exception of always permitted
18966                 // Shell broadcasts
18967                 if (callingUid == SHELL_UID
18968                         && mUserController.hasUserRestriction(
18969                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
18970                         && !isPermittedShellBroadcast(intent)) {
18971                     continue;
18972                 }
18973                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
18974                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
18975                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
18976                     // If this is not the system user, we need to check for
18977                     // any receivers that should be filtered out.
18978                     for (int i=0; i<newReceivers.size(); i++) {
18979                         ResolveInfo ri = newReceivers.get(i);
18980                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
18981                             newReceivers.remove(i);
18982                             i--;
18983                         }
18984                     }
18985                 }
18986                 if (newReceivers != null && newReceivers.size() == 0) {
18987                     newReceivers = null;
18988                 }
18989                 if (receivers == null) {
18990                     receivers = newReceivers;
18991                 } else if (newReceivers != null) {
18992                     // We need to concatenate the additional receivers
18993                     // found with what we have do far.  This would be easy,
18994                     // but we also need to de-dup any receivers that are
18995                     // singleUser.
18996                     if (!scannedFirstReceivers) {
18997                         // Collect any single user receivers we had already retrieved.
18998                         scannedFirstReceivers = true;
18999                         for (int i=0; i<receivers.size(); i++) {
19000                             ResolveInfo ri = receivers.get(i);
19001                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19002                                 ComponentName cn = new ComponentName(
19003                                         ri.activityInfo.packageName, ri.activityInfo.name);
19004                                 if (singleUserReceivers == null) {
19005                                     singleUserReceivers = new HashSet<ComponentName>();
19006                                 }
19007                                 singleUserReceivers.add(cn);
19008                             }
19009                         }
19010                     }
19011                     // Add the new results to the existing results, tracking
19012                     // and de-dupping single user receivers.
19013                     for (int i=0; i<newReceivers.size(); i++) {
19014                         ResolveInfo ri = newReceivers.get(i);
19015                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
19016                             ComponentName cn = new ComponentName(
19017                                     ri.activityInfo.packageName, ri.activityInfo.name);
19018                             if (singleUserReceivers == null) {
19019                                 singleUserReceivers = new HashSet<ComponentName>();
19020                             }
19021                             if (!singleUserReceivers.contains(cn)) {
19022                                 singleUserReceivers.add(cn);
19023                                 receivers.add(ri);
19024                             }
19025                         } else {
19026                             receivers.add(ri);
19027                         }
19028                     }
19029                 }
19030             }
19031         } catch (RemoteException ex) {
19032             // pm is in same process, this will never happen.
19033         }
19034         return receivers;
19035     }
19036
19037     private boolean isPermittedShellBroadcast(Intent intent) {
19038         // remote bugreport should always be allowed to be taken
19039         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
19040     }
19041
19042     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
19043             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
19044         if ((intent.getFlags() & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19045             // Don't yell about broadcasts sent via shell
19046             return;
19047         }
19048
19049         final String action = intent.getAction();
19050         if (isProtectedBroadcast
19051                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
19052                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
19053                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
19054                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
19055                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
19056                 || Intent.ACTION_MASTER_CLEAR.equals(action)
19057                 || Intent.ACTION_FACTORY_RESET.equals(action)
19058                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19059                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
19060                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
19061                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
19062                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)
19063                 || AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION.equals(action)
19064                 || AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION.equals(action)) {
19065             // Broadcast is either protected, or it's a public action that
19066             // we've relaxed, so it's fine for system internals to send.
19067             return;
19068         }
19069
19070         // This broadcast may be a problem...  but there are often system components that
19071         // want to send an internal broadcast to themselves, which is annoying to have to
19072         // explicitly list each action as a protected broadcast, so we will check for that
19073         // one safe case and allow it: an explicit broadcast, only being received by something
19074         // that has protected itself.
19075         if (receivers != null && receivers.size() > 0
19076                 && (intent.getPackage() != null || intent.getComponent() != null)) {
19077             boolean allProtected = true;
19078             for (int i = receivers.size()-1; i >= 0; i--) {
19079                 Object target = receivers.get(i);
19080                 if (target instanceof ResolveInfo) {
19081                     ResolveInfo ri = (ResolveInfo)target;
19082                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
19083                         allProtected = false;
19084                         break;
19085                     }
19086                 } else {
19087                     BroadcastFilter bf = (BroadcastFilter)target;
19088                     if (bf.requiredPermission == null) {
19089                         allProtected = false;
19090                         break;
19091                     }
19092                 }
19093             }
19094             if (allProtected) {
19095                 // All safe!
19096                 return;
19097             }
19098         }
19099
19100         // The vast majority of broadcasts sent from system internals
19101         // should be protected to avoid security holes, so yell loudly
19102         // to ensure we examine these cases.
19103         if (callerApp != null) {
19104             Log.wtf(TAG, "Sending non-protected broadcast " + action
19105                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
19106                     new Throwable());
19107         } else {
19108             Log.wtf(TAG, "Sending non-protected broadcast " + action
19109                             + " from system uid " + UserHandle.formatUid(callingUid)
19110                             + " pkg " + callerPackage,
19111                     new Throwable());
19112         }
19113     }
19114
19115     final int broadcastIntentLocked(ProcessRecord callerApp,
19116             String callerPackage, Intent intent, String resolvedType,
19117             IIntentReceiver resultTo, int resultCode, String resultData,
19118             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
19119             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
19120         intent = new Intent(intent);
19121
19122         final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
19123         // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
19124         if (callerInstantApp) {
19125             intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
19126         }
19127
19128         // By default broadcasts do not go to stopped apps.
19129         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
19130
19131         // If we have not finished booting, don't allow this to launch new processes.
19132         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
19133             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19134         }
19135
19136         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
19137                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
19138                 + " ordered=" + ordered + " userid=" + userId);
19139         if ((resultTo != null) && !ordered) {
19140             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
19141         }
19142
19143         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
19144                 ALLOW_NON_FULL, "broadcast", callerPackage);
19145
19146         // Make sure that the user who is receiving this broadcast is running.
19147         // If not, we will just skip it. Make an exception for shutdown broadcasts
19148         // and upgrade steps.
19149
19150         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
19151             if ((callingUid != SYSTEM_UID
19152                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
19153                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
19154                 Slog.w(TAG, "Skipping broadcast of " + intent
19155                         + ": user " + userId + " is stopped");
19156                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
19157             }
19158         }
19159
19160         BroadcastOptions brOptions = null;
19161         if (bOptions != null) {
19162             brOptions = new BroadcastOptions(bOptions);
19163             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
19164                 // See if the caller is allowed to do this.  Note we are checking against
19165                 // the actual real caller (not whoever provided the operation as say a
19166                 // PendingIntent), because that who is actually supplied the arguments.
19167                 if (checkComponentPermission(
19168                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
19169                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
19170                         != PackageManager.PERMISSION_GRANTED) {
19171                     String msg = "Permission Denial: " + intent.getAction()
19172                             + " broadcast from " + callerPackage + " (pid=" + callingPid
19173                             + ", uid=" + callingUid + ")"
19174                             + " requires "
19175                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
19176                     Slog.w(TAG, msg);
19177                     throw new SecurityException(msg);
19178                 }
19179             }
19180         }
19181
19182         // Verify that protected broadcasts are only being sent by system code,
19183         // and that system code is only sending protected broadcasts.
19184         final String action = intent.getAction();
19185         final boolean isProtectedBroadcast;
19186         try {
19187             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
19188         } catch (RemoteException e) {
19189             Slog.w(TAG, "Remote exception", e);
19190             return ActivityManager.BROADCAST_SUCCESS;
19191         }
19192
19193         final boolean isCallerSystem;
19194         switch (UserHandle.getAppId(callingUid)) {
19195             case ROOT_UID:
19196             case SYSTEM_UID:
19197             case PHONE_UID:
19198             case BLUETOOTH_UID:
19199             case NFC_UID:
19200                 isCallerSystem = true;
19201                 break;
19202             default:
19203                 isCallerSystem = (callerApp != null) && callerApp.persistent;
19204                 break;
19205         }
19206
19207         // First line security check before anything else: stop non-system apps from
19208         // sending protected broadcasts.
19209         if (!isCallerSystem) {
19210             if (isProtectedBroadcast) {
19211                 String msg = "Permission Denial: not allowed to send broadcast "
19212                         + action + " from pid="
19213                         + callingPid + ", uid=" + callingUid;
19214                 Slog.w(TAG, msg);
19215                 throw new SecurityException(msg);
19216
19217             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
19218                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
19219                 // Special case for compatibility: we don't want apps to send this,
19220                 // but historically it has not been protected and apps may be using it
19221                 // to poke their own app widget.  So, instead of making it protected,
19222                 // just limit it to the caller.
19223                 if (callerPackage == null) {
19224                     String msg = "Permission Denial: not allowed to send broadcast "
19225                             + action + " from unknown caller.";
19226                     Slog.w(TAG, msg);
19227                     throw new SecurityException(msg);
19228                 } else if (intent.getComponent() != null) {
19229                     // They are good enough to send to an explicit component...  verify
19230                     // it is being sent to the calling app.
19231                     if (!intent.getComponent().getPackageName().equals(
19232                             callerPackage)) {
19233                         String msg = "Permission Denial: not allowed to send broadcast "
19234                                 + action + " to "
19235                                 + intent.getComponent().getPackageName() + " from "
19236                                 + callerPackage;
19237                         Slog.w(TAG, msg);
19238                         throw new SecurityException(msg);
19239                     }
19240                 } else {
19241                     // Limit broadcast to their own package.
19242                     intent.setPackage(callerPackage);
19243                 }
19244             }
19245         }
19246
19247         if (action != null) {
19248             if (getBackgroundLaunchBroadcasts().contains(action)) {
19249                 if (DEBUG_BACKGROUND_CHECK) {
19250                     Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
19251                 }
19252                 intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
19253             }
19254
19255             switch (action) {
19256                 case Intent.ACTION_UID_REMOVED:
19257                 case Intent.ACTION_PACKAGE_REMOVED:
19258                 case Intent.ACTION_PACKAGE_CHANGED:
19259                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19260                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19261                 case Intent.ACTION_PACKAGES_SUSPENDED:
19262                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
19263                     // Handle special intents: if this broadcast is from the package
19264                     // manager about a package being removed, we need to remove all of
19265                     // its activities from the history stack.
19266                     if (checkComponentPermission(
19267                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
19268                             callingPid, callingUid, -1, true)
19269                             != PackageManager.PERMISSION_GRANTED) {
19270                         String msg = "Permission Denial: " + intent.getAction()
19271                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
19272                                 + ", uid=" + callingUid + ")"
19273                                 + " requires "
19274                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
19275                         Slog.w(TAG, msg);
19276                         throw new SecurityException(msg);
19277                     }
19278                     switch (action) {
19279                         case Intent.ACTION_UID_REMOVED:
19280                             final int uid = getUidFromIntent(intent);
19281                             if (uid >= 0) {
19282                                 mBatteryStatsService.removeUid(uid);
19283                                 mAppOpsService.uidRemoved(uid);
19284                             }
19285                             break;
19286                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
19287                             // If resources are unavailable just force stop all those packages
19288                             // and flush the attribute cache as well.
19289                             String list[] =
19290                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19291                             if (list != null && list.length > 0) {
19292                                 for (int i = 0; i < list.length; i++) {
19293                                     forceStopPackageLocked(list[i], -1, false, true, true,
19294                                             false, false, userId, "storage unmount");
19295                                 }
19296                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19297                                 sendPackageBroadcastLocked(
19298                                         ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
19299                                         list, userId);
19300                             }
19301                             break;
19302                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
19303                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
19304                             break;
19305                         case Intent.ACTION_PACKAGE_REMOVED:
19306                         case Intent.ACTION_PACKAGE_CHANGED:
19307                             Uri data = intent.getData();
19308                             String ssp;
19309                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
19310                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
19311                                 final boolean replacing =
19312                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19313                                 final boolean killProcess =
19314                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
19315                                 final boolean fullUninstall = removed && !replacing;
19316                                 if (removed) {
19317                                     if (killProcess) {
19318                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
19319                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19320                                                 false, true, true, false, fullUninstall, userId,
19321                                                 removed ? "pkg removed" : "pkg changed");
19322                                     }
19323                                     final int cmd = killProcess
19324                                             ? ApplicationThreadConstants.PACKAGE_REMOVED
19325                                             : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
19326                                     sendPackageBroadcastLocked(cmd,
19327                                             new String[] {ssp}, userId);
19328                                     if (fullUninstall) {
19329                                         mAppOpsService.packageRemoved(
19330                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
19331
19332                                         // Remove all permissions granted from/to this package
19333                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
19334
19335                                         removeTasksByPackageNameLocked(ssp, userId);
19336
19337                                         mServices.forceStopPackageLocked(ssp, userId);
19338
19339                                         // Hide the "unsupported display" dialog if necessary.
19340                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19341                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19342                                             mUnsupportedDisplaySizeDialog.dismiss();
19343                                             mUnsupportedDisplaySizeDialog = null;
19344                                         }
19345                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
19346                                         mBatteryStatsService.notePackageUninstalled(ssp);
19347                                     }
19348                                 } else {
19349                                     if (killProcess) {
19350                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
19351                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
19352                                                 userId, ProcessList.INVALID_ADJ,
19353                                                 false, true, true, false, "change " + ssp);
19354                                     }
19355                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
19356                                             intent.getStringArrayExtra(
19357                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
19358                                 }
19359                             }
19360                             break;
19361                         case Intent.ACTION_PACKAGES_SUSPENDED:
19362                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
19363                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
19364                                     intent.getAction());
19365                             final String[] packageNames = intent.getStringArrayExtra(
19366                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
19367                             final int userHandle = intent.getIntExtra(
19368                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
19369
19370                             synchronized(ActivityManagerService.this) {
19371                                 mRecentTasks.onPackagesSuspendedChanged(
19372                                         packageNames, suspended, userHandle);
19373                             }
19374                             break;
19375                     }
19376                     break;
19377                 case Intent.ACTION_PACKAGE_REPLACED:
19378                 {
19379                     final Uri data = intent.getData();
19380                     final String ssp;
19381                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19382                         ApplicationInfo aInfo = null;
19383                         try {
19384                             aInfo = AppGlobals.getPackageManager()
19385                                     .getApplicationInfo(ssp, 0 /*flags*/, userId);
19386                         } catch (RemoteException ignore) {}
19387                         if (aInfo == null) {
19388                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
19389                                     + " ssp=" + ssp + " data=" + data);
19390                             return ActivityManager.BROADCAST_SUCCESS;
19391                         }
19392                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
19393                         sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
19394                                 new String[] {ssp}, userId);
19395                     }
19396                     break;
19397                 }
19398                 case Intent.ACTION_PACKAGE_ADDED:
19399                 {
19400                     // Special case for adding a package: by default turn on compatibility mode.
19401                     Uri data = intent.getData();
19402                     String ssp;
19403                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19404                         final boolean replacing =
19405                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
19406                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
19407
19408                         try {
19409                             ApplicationInfo ai = AppGlobals.getPackageManager().
19410                                     getApplicationInfo(ssp, 0, 0);
19411                             mBatteryStatsService.notePackageInstalled(ssp,
19412                                     ai != null ? ai.versionCode : 0);
19413                         } catch (RemoteException e) {
19414                         }
19415                     }
19416                     break;
19417                 }
19418                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
19419                 {
19420                     Uri data = intent.getData();
19421                     String ssp;
19422                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
19423                         // Hide the "unsupported display" dialog if necessary.
19424                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
19425                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
19426                             mUnsupportedDisplaySizeDialog.dismiss();
19427                             mUnsupportedDisplaySizeDialog = null;
19428                         }
19429                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
19430                     }
19431                     break;
19432                 }
19433                 case Intent.ACTION_TIMEZONE_CHANGED:
19434                     // If this is the time zone changed action, queue up a message that will reset
19435                     // the timezone of all currently running processes. This message will get
19436                     // queued up before the broadcast happens.
19437                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
19438                     break;
19439                 case Intent.ACTION_TIME_CHANGED:
19440                     // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
19441                     // the tri-state value it may contain and "unknown".
19442                     // For convenience we re-use the Intent extra values.
19443                     final int NO_EXTRA_VALUE_FOUND = -1;
19444                     final int timeFormatPreferenceMsgValue = intent.getIntExtra(
19445                             Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
19446                             NO_EXTRA_VALUE_FOUND /* defaultValue */);
19447                     // Only send a message if the time preference is available.
19448                     if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
19449                         Message updateTimePreferenceMsg =
19450                                 mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
19451                                         timeFormatPreferenceMsgValue, 0);
19452                         mHandler.sendMessage(updateTimePreferenceMsg);
19453                     }
19454                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19455                     synchronized (stats) {
19456                         stats.noteCurrentTimeChangedLocked();
19457                     }
19458                     break;
19459                 case Intent.ACTION_CLEAR_DNS_CACHE:
19460                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
19461                     break;
19462                 case Proxy.PROXY_CHANGE_ACTION:
19463                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
19464                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
19465                     break;
19466                 case android.hardware.Camera.ACTION_NEW_PICTURE:
19467                 case android.hardware.Camera.ACTION_NEW_VIDEO:
19468                     // In N we just turned these off; in O we are turing them back on partly,
19469                     // only for registered receivers.  This will still address the main problem
19470                     // (a spam of apps waking up when a picture is taken putting significant
19471                     // memory pressure on the system at a bad point), while still allowing apps
19472                     // that are already actively running to know about this happening.
19473                     intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19474                     break;
19475                 case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
19476                     mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
19477                     break;
19478                 case "com.android.launcher.action.INSTALL_SHORTCUT":
19479                     // As of O, we no longer support this broadcasts, even for pre-O apps.
19480                     // Apps should now be using ShortcutManager.pinRequestShortcut().
19481                     Log.w(TAG, "Broadcast " + action
19482                             + " no longer supported. It will not be delivered.");
19483                     return ActivityManager.BROADCAST_SUCCESS;
19484             }
19485
19486             if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
19487                     Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
19488                     Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
19489                 final int uid = getUidFromIntent(intent);
19490                 if (uid != -1) {
19491                     final UidRecord uidRec = mActiveUids.get(uid);
19492                     if (uidRec != null) {
19493                         uidRec.updateHasInternetPermission();
19494                     }
19495                 }
19496             }
19497         }
19498
19499         // Add to the sticky list if requested.
19500         if (sticky) {
19501             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
19502                     callingPid, callingUid)
19503                     != PackageManager.PERMISSION_GRANTED) {
19504                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
19505                         + callingPid + ", uid=" + callingUid
19506                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19507                 Slog.w(TAG, msg);
19508                 throw new SecurityException(msg);
19509             }
19510             if (requiredPermissions != null && requiredPermissions.length > 0) {
19511                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
19512                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
19513                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
19514             }
19515             if (intent.getComponent() != null) {
19516                 throw new SecurityException(
19517                         "Sticky broadcasts can't target a specific component");
19518             }
19519             // We use userId directly here, since the "all" target is maintained
19520             // as a separate set of sticky broadcasts.
19521             if (userId != UserHandle.USER_ALL) {
19522                 // But first, if this is not a broadcast to all users, then
19523                 // make sure it doesn't conflict with an existing broadcast to
19524                 // all users.
19525                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
19526                         UserHandle.USER_ALL);
19527                 if (stickies != null) {
19528                     ArrayList<Intent> list = stickies.get(intent.getAction());
19529                     if (list != null) {
19530                         int N = list.size();
19531                         int i;
19532                         for (i=0; i<N; i++) {
19533                             if (intent.filterEquals(list.get(i))) {
19534                                 throw new IllegalArgumentException(
19535                                         "Sticky broadcast " + intent + " for user "
19536                                         + userId + " conflicts with existing global broadcast");
19537                             }
19538                         }
19539                     }
19540                 }
19541             }
19542             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19543             if (stickies == null) {
19544                 stickies = new ArrayMap<>();
19545                 mStickyBroadcasts.put(userId, stickies);
19546             }
19547             ArrayList<Intent> list = stickies.get(intent.getAction());
19548             if (list == null) {
19549                 list = new ArrayList<>();
19550                 stickies.put(intent.getAction(), list);
19551             }
19552             final int stickiesCount = list.size();
19553             int i;
19554             for (i = 0; i < stickiesCount; i++) {
19555                 if (intent.filterEquals(list.get(i))) {
19556                     // This sticky already exists, replace it.
19557                     list.set(i, new Intent(intent));
19558                     break;
19559                 }
19560             }
19561             if (i >= stickiesCount) {
19562                 list.add(new Intent(intent));
19563             }
19564         }
19565
19566         int[] users;
19567         if (userId == UserHandle.USER_ALL) {
19568             // Caller wants broadcast to go to all started users.
19569             users = mUserController.getStartedUserArrayLocked();
19570         } else {
19571             // Caller wants broadcast to go to one specific user.
19572             users = new int[] {userId};
19573         }
19574
19575         // Figure out who all will receive this broadcast.
19576         List receivers = null;
19577         List<BroadcastFilter> registeredReceivers = null;
19578         // Need to resolve the intent to interested receivers...
19579         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
19580                  == 0) {
19581             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
19582         }
19583         if (intent.getComponent() == null) {
19584             if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
19585                 // Query one target user at a time, excluding shell-restricted users
19586                 for (int i = 0; i < users.length; i++) {
19587                     if (mUserController.hasUserRestriction(
19588                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
19589                         continue;
19590                     }
19591                     List<BroadcastFilter> registeredReceiversForUser =
19592                             mReceiverResolver.queryIntent(intent,
19593                                     resolvedType, false /*defaultOnly*/, users[i]);
19594                     if (registeredReceivers == null) {
19595                         registeredReceivers = registeredReceiversForUser;
19596                     } else if (registeredReceiversForUser != null) {
19597                         registeredReceivers.addAll(registeredReceiversForUser);
19598                     }
19599                 }
19600             } else {
19601                 registeredReceivers = mReceiverResolver.queryIntent(intent,
19602                         resolvedType, false /*defaultOnly*/, userId);
19603             }
19604         }
19605
19606         final boolean replacePending =
19607                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
19608
19609         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
19610                 + " replacePending=" + replacePending);
19611
19612         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
19613         if (!ordered && NR > 0) {
19614             // If we are not serializing this broadcast, then send the
19615             // registered receivers separately so they don't wait for the
19616             // components to be launched.
19617             if (isCallerSystem) {
19618                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19619                         isProtectedBroadcast, registeredReceivers);
19620             }
19621             final BroadcastQueue queue = broadcastQueueForIntent(intent);
19622             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19623                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19624                     requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
19625                     resultCode, resultData, resultExtras, ordered, sticky, false, userId);
19626             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
19627             final boolean replaced = replacePending
19628                     && (queue.replaceParallelBroadcastLocked(r) != null);
19629             // Note: We assume resultTo is null for non-ordered broadcasts.
19630             if (!replaced) {
19631                 queue.enqueueParallelBroadcastLocked(r);
19632                 queue.scheduleBroadcastsLocked();
19633             }
19634             registeredReceivers = null;
19635             NR = 0;
19636         }
19637
19638         // Merge into one list.
19639         int ir = 0;
19640         if (receivers != null) {
19641             // A special case for PACKAGE_ADDED: do not allow the package
19642             // being added to see this broadcast.  This prevents them from
19643             // using this as a back door to get run as soon as they are
19644             // installed.  Maybe in the future we want to have a special install
19645             // broadcast or such for apps, but we'd like to deliberately make
19646             // this decision.
19647             String skipPackages[] = null;
19648             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
19649                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
19650                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
19651                 Uri data = intent.getData();
19652                 if (data != null) {
19653                     String pkgName = data.getSchemeSpecificPart();
19654                     if (pkgName != null) {
19655                         skipPackages = new String[] { pkgName };
19656                     }
19657                 }
19658             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
19659                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
19660             }
19661             if (skipPackages != null && (skipPackages.length > 0)) {
19662                 for (String skipPackage : skipPackages) {
19663                     if (skipPackage != null) {
19664                         int NT = receivers.size();
19665                         for (int it=0; it<NT; it++) {
19666                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
19667                             if (curt.activityInfo.packageName.equals(skipPackage)) {
19668                                 receivers.remove(it);
19669                                 it--;
19670                                 NT--;
19671                             }
19672                         }
19673                     }
19674                 }
19675             }
19676
19677             int NT = receivers != null ? receivers.size() : 0;
19678             int it = 0;
19679             ResolveInfo curt = null;
19680             BroadcastFilter curr = null;
19681             while (it < NT && ir < NR) {
19682                 if (curt == null) {
19683                     curt = (ResolveInfo)receivers.get(it);
19684                 }
19685                 if (curr == null) {
19686                     curr = registeredReceivers.get(ir);
19687                 }
19688                 if (curr.getPriority() >= curt.priority) {
19689                     // Insert this broadcast record into the final list.
19690                     receivers.add(it, curr);
19691                     ir++;
19692                     curr = null;
19693                     it++;
19694                     NT++;
19695                 } else {
19696                     // Skip to the next ResolveInfo in the final list.
19697                     it++;
19698                     curt = null;
19699                 }
19700             }
19701         }
19702         while (ir < NR) {
19703             if (receivers == null) {
19704                 receivers = new ArrayList();
19705             }
19706             receivers.add(registeredReceivers.get(ir));
19707             ir++;
19708         }
19709
19710         if (isCallerSystem) {
19711             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
19712                     isProtectedBroadcast, receivers);
19713         }
19714
19715         if ((receivers != null && receivers.size() > 0)
19716                 || resultTo != null) {
19717             BroadcastQueue queue = broadcastQueueForIntent(intent);
19718             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
19719                     callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
19720                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
19721                     resultData, resultExtras, ordered, sticky, false, userId);
19722
19723             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
19724                     + ": prev had " + queue.mOrderedBroadcasts.size());
19725             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
19726                     "Enqueueing broadcast " + r.intent.getAction());
19727
19728             final BroadcastRecord oldRecord =
19729                     replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
19730             if (oldRecord != null) {
19731                 // Replaced, fire the result-to receiver.
19732                 if (oldRecord.resultTo != null) {
19733                     final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
19734                     try {
19735                         oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
19736                                 oldRecord.intent,
19737                                 Activity.RESULT_CANCELED, null, null,
19738                                 false, false, oldRecord.userId);
19739                     } catch (RemoteException e) {
19740                         Slog.w(TAG, "Failure ["
19741                                 + queue.mQueueName + "] sending broadcast result of "
19742                                 + intent, e);
19743
19744                     }
19745                 }
19746             } else {
19747                 queue.enqueueOrderedBroadcastLocked(r);
19748                 queue.scheduleBroadcastsLocked();
19749             }
19750         } else {
19751             // There was nobody interested in the broadcast, but we still want to record
19752             // that it happened.
19753             if (intent.getComponent() == null && intent.getPackage() == null
19754                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19755                 // This was an implicit broadcast... let's record it for posterity.
19756                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
19757             }
19758         }
19759
19760         return ActivityManager.BROADCAST_SUCCESS;
19761     }
19762
19763     /**
19764      * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
19765      */
19766     private int getUidFromIntent(Intent intent) {
19767         if (intent == null) {
19768             return -1;
19769         }
19770         final Bundle intentExtras = intent.getExtras();
19771         return intent.hasExtra(Intent.EXTRA_UID)
19772                 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
19773     }
19774
19775     final void rotateBroadcastStatsIfNeededLocked() {
19776         final long now = SystemClock.elapsedRealtime();
19777         if (mCurBroadcastStats == null ||
19778                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
19779             mLastBroadcastStats = mCurBroadcastStats;
19780             if (mLastBroadcastStats != null) {
19781                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
19782                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
19783             }
19784             mCurBroadcastStats = new BroadcastStats();
19785         }
19786     }
19787
19788     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
19789             int skipCount, long dispatchTime) {
19790         rotateBroadcastStatsIfNeededLocked();
19791         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
19792     }
19793
19794     final void addBackgroundCheckViolationLocked(String action, String targetPackage) {
19795         rotateBroadcastStatsIfNeededLocked();
19796         mCurBroadcastStats.addBackgroundCheckViolation(action, targetPackage);
19797     }
19798
19799     final Intent verifyBroadcastLocked(Intent intent) {
19800         // Refuse possible leaked file descriptors
19801         if (intent != null && intent.hasFileDescriptors() == true) {
19802             throw new IllegalArgumentException("File descriptors passed in Intent");
19803         }
19804
19805         int flags = intent.getFlags();
19806
19807         if (!mProcessesReady) {
19808             // if the caller really truly claims to know what they're doing, go
19809             // ahead and allow the broadcast without launching any receivers
19810             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
19811                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
19812             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
19813                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
19814                         + " before boot completion");
19815                 throw new IllegalStateException("Cannot broadcast before boot completed");
19816             }
19817         }
19818
19819         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
19820             throw new IllegalArgumentException(
19821                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
19822         }
19823
19824         if ((flags & Intent.FLAG_RECEIVER_FROM_SHELL) != 0) {
19825             switch (Binder.getCallingUid()) {
19826                 case ROOT_UID:
19827                 case SHELL_UID:
19828                     break;
19829                 default:
19830                     Slog.w(TAG, "Removing FLAG_RECEIVER_FROM_SHELL because caller is UID "
19831                             + Binder.getCallingUid());
19832                     intent.removeFlags(Intent.FLAG_RECEIVER_FROM_SHELL);
19833                     break;
19834             }
19835         }
19836
19837         return intent;
19838     }
19839
19840     public final int broadcastIntent(IApplicationThread caller,
19841             Intent intent, String resolvedType, IIntentReceiver resultTo,
19842             int resultCode, String resultData, Bundle resultExtras,
19843             String[] requiredPermissions, int appOp, Bundle bOptions,
19844             boolean serialized, boolean sticky, int userId) {
19845         enforceNotIsolatedCaller("broadcastIntent");
19846         synchronized(this) {
19847             intent = verifyBroadcastLocked(intent);
19848
19849             final ProcessRecord callerApp = getRecordForAppLocked(caller);
19850             final int callingPid = Binder.getCallingPid();
19851             final int callingUid = Binder.getCallingUid();
19852             final long origId = Binder.clearCallingIdentity();
19853             int res = broadcastIntentLocked(callerApp,
19854                     callerApp != null ? callerApp.info.packageName : null,
19855                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
19856                     requiredPermissions, appOp, bOptions, serialized, sticky,
19857                     callingPid, callingUid, userId);
19858             Binder.restoreCallingIdentity(origId);
19859             return res;
19860         }
19861     }
19862
19863
19864     int broadcastIntentInPackage(String packageName, int uid,
19865             Intent intent, String resolvedType, IIntentReceiver resultTo,
19866             int resultCode, String resultData, Bundle resultExtras,
19867             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
19868             int userId) {
19869         synchronized(this) {
19870             intent = verifyBroadcastLocked(intent);
19871
19872             final long origId = Binder.clearCallingIdentity();
19873             String[] requiredPermissions = requiredPermission == null ? null
19874                     : new String[] {requiredPermission};
19875             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
19876                     resultTo, resultCode, resultData, resultExtras,
19877                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
19878                     sticky, -1, uid, userId);
19879             Binder.restoreCallingIdentity(origId);
19880             return res;
19881         }
19882     }
19883
19884     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
19885         // Refuse possible leaked file descriptors
19886         if (intent != null && intent.hasFileDescriptors() == true) {
19887             throw new IllegalArgumentException("File descriptors passed in Intent");
19888         }
19889
19890         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19891                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
19892
19893         synchronized(this) {
19894             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
19895                     != PackageManager.PERMISSION_GRANTED) {
19896                 String msg = "Permission Denial: unbroadcastIntent() from pid="
19897                         + Binder.getCallingPid()
19898                         + ", uid=" + Binder.getCallingUid()
19899                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
19900                 Slog.w(TAG, msg);
19901                 throw new SecurityException(msg);
19902             }
19903             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
19904             if (stickies != null) {
19905                 ArrayList<Intent> list = stickies.get(intent.getAction());
19906                 if (list != null) {
19907                     int N = list.size();
19908                     int i;
19909                     for (i=0; i<N; i++) {
19910                         if (intent.filterEquals(list.get(i))) {
19911                             list.remove(i);
19912                             break;
19913                         }
19914                     }
19915                     if (list.size() <= 0) {
19916                         stickies.remove(intent.getAction());
19917                     }
19918                 }
19919                 if (stickies.size() <= 0) {
19920                     mStickyBroadcasts.remove(userId);
19921                 }
19922             }
19923         }
19924     }
19925
19926     void backgroundServicesFinishedLocked(int userId) {
19927         for (BroadcastQueue queue : mBroadcastQueues) {
19928             queue.backgroundServicesFinishedLocked(userId);
19929         }
19930     }
19931
19932     public void finishReceiver(IBinder who, int resultCode, String resultData,
19933             Bundle resultExtras, boolean resultAbort, int flags) {
19934         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
19935
19936         // Refuse possible leaked file descriptors
19937         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
19938             throw new IllegalArgumentException("File descriptors passed in Bundle");
19939         }
19940
19941         final long origId = Binder.clearCallingIdentity();
19942         try {
19943             boolean doNext = false;
19944             BroadcastRecord r;
19945
19946             synchronized(this) {
19947                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
19948                         ? mFgBroadcastQueue : mBgBroadcastQueue;
19949                 r = queue.getMatchingOrderedReceiver(who);
19950                 if (r != null) {
19951                     doNext = r.queue.finishReceiverLocked(r, resultCode,
19952                         resultData, resultExtras, resultAbort, true);
19953                 }
19954             }
19955
19956             if (doNext) {
19957                 r.queue.processNextBroadcast(false);
19958             }
19959             trimApplications();
19960         } finally {
19961             Binder.restoreCallingIdentity(origId);
19962         }
19963     }
19964
19965     // =========================================================
19966     // INSTRUMENTATION
19967     // =========================================================
19968
19969     public boolean startInstrumentation(ComponentName className,
19970             String profileFile, int flags, Bundle arguments,
19971             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
19972             int userId, String abiOverride) {
19973         enforceNotIsolatedCaller("startInstrumentation");
19974         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19975                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
19976         // Refuse possible leaked file descriptors
19977         if (arguments != null && arguments.hasFileDescriptors()) {
19978             throw new IllegalArgumentException("File descriptors passed in Bundle");
19979         }
19980
19981         synchronized(this) {
19982             InstrumentationInfo ii = null;
19983             ApplicationInfo ai = null;
19984             try {
19985                 ii = mContext.getPackageManager().getInstrumentationInfo(
19986                     className, STOCK_PM_FLAGS);
19987                 ai = AppGlobals.getPackageManager().getApplicationInfo(
19988                         ii.targetPackage, STOCK_PM_FLAGS, userId);
19989             } catch (PackageManager.NameNotFoundException e) {
19990             } catch (RemoteException e) {
19991             }
19992             if (ii == null) {
19993                 reportStartInstrumentationFailureLocked(watcher, className,
19994                         "Unable to find instrumentation info for: " + className);
19995                 return false;
19996             }
19997             if (ai == null) {
19998                 reportStartInstrumentationFailureLocked(watcher, className,
19999                         "Unable to find instrumentation target package: " + ii.targetPackage);
20000                 return false;
20001             }
20002             if (!ai.hasCode()) {
20003                 reportStartInstrumentationFailureLocked(watcher, className,
20004                         "Instrumentation target has no code: " + ii.targetPackage);
20005                 return false;
20006             }
20007
20008             int match = mContext.getPackageManager().checkSignatures(
20009                     ii.targetPackage, ii.packageName);
20010             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
20011                 String msg = "Permission Denial: starting instrumentation "
20012                         + className + " from pid="
20013                         + Binder.getCallingPid()
20014                         + ", uid=" + Binder.getCallingPid()
20015                         + " not allowed because package " + ii.packageName
20016                         + " does not have a signature matching the target "
20017                         + ii.targetPackage;
20018                 reportStartInstrumentationFailureLocked(watcher, className, msg);
20019                 throw new SecurityException(msg);
20020             }
20021
20022             ActiveInstrumentation activeInstr = new ActiveInstrumentation(this);
20023             activeInstr.mClass = className;
20024             String defProcess = ai.processName;;
20025             if (ii.targetProcesses == null) {
20026                 activeInstr.mTargetProcesses = new String[]{ai.processName};
20027             } else if (ii.targetProcesses.equals("*")) {
20028                 activeInstr.mTargetProcesses = new String[0];
20029             } else {
20030                 activeInstr.mTargetProcesses = ii.targetProcesses.split(",");
20031                 defProcess = activeInstr.mTargetProcesses[0];
20032             }
20033             activeInstr.mTargetInfo = ai;
20034             activeInstr.mProfileFile = profileFile;
20035             activeInstr.mArguments = arguments;
20036             activeInstr.mWatcher = watcher;
20037             activeInstr.mUiAutomationConnection = uiAutomationConnection;
20038             activeInstr.mResultClass = className;
20039
20040             final long origId = Binder.clearCallingIdentity();
20041             // Instrumentation can kill and relaunch even persistent processes
20042             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
20043                     "start instr");
20044             ProcessRecord app = addAppLocked(ai, defProcess, false, abiOverride);
20045             app.instr = activeInstr;
20046             activeInstr.mFinished = false;
20047             activeInstr.mRunningProcesses.add(app);
20048             if (!mActiveInstrumentation.contains(activeInstr)) {
20049                 mActiveInstrumentation.add(activeInstr);
20050             }
20051             Binder.restoreCallingIdentity(origId);
20052         }
20053
20054         return true;
20055     }
20056
20057     /**
20058      * Report errors that occur while attempting to start Instrumentation.  Always writes the
20059      * error to the logs, but if somebody is watching, send the report there too.  This enables
20060      * the "am" command to report errors with more information.
20061      *
20062      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
20063      * @param cn The component name of the instrumentation.
20064      * @param report The error report.
20065      */
20066     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
20067             ComponentName cn, String report) {
20068         Slog.w(TAG, report);
20069         if (watcher != null) {
20070             Bundle results = new Bundle();
20071             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
20072             results.putString("Error", report);
20073             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
20074         }
20075     }
20076
20077     void addInstrumentationResultsLocked(ProcessRecord app, Bundle results) {
20078         if (app.instr == null) {
20079             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20080             return;
20081         }
20082
20083         if (!app.instr.mFinished && results != null) {
20084             if (app.instr.mCurResults == null) {
20085                 app.instr.mCurResults = new Bundle(results);
20086             } else {
20087                 app.instr.mCurResults.putAll(results);
20088             }
20089         }
20090     }
20091
20092     public void addInstrumentationResults(IApplicationThread target, Bundle results) {
20093         int userId = UserHandle.getCallingUserId();
20094         // Refuse possible leaked file descriptors
20095         if (results != null && results.hasFileDescriptors()) {
20096             throw new IllegalArgumentException("File descriptors passed in Intent");
20097         }
20098
20099         synchronized(this) {
20100             ProcessRecord app = getRecordForAppLocked(target);
20101             if (app == null) {
20102                 Slog.w(TAG, "addInstrumentationResults: no app for " + target);
20103                 return;
20104             }
20105             final long origId = Binder.clearCallingIdentity();
20106             addInstrumentationResultsLocked(app, results);
20107             Binder.restoreCallingIdentity(origId);
20108         }
20109     }
20110
20111     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
20112         if (app.instr == null) {
20113             Slog.w(TAG, "finishInstrumentation called on non-instrumented: " + app);
20114             return;
20115         }
20116
20117         if (!app.instr.mFinished) {
20118             if (app.instr.mWatcher != null) {
20119                 Bundle finalResults = app.instr.mCurResults;
20120                 if (finalResults != null) {
20121                     if (app.instr.mCurResults != null && results != null) {
20122                         finalResults.putAll(results);
20123                     }
20124                 } else {
20125                     finalResults = results;
20126                 }
20127                 mInstrumentationReporter.reportFinished(app.instr.mWatcher,
20128                         app.instr.mClass, resultCode, finalResults);
20129             }
20130
20131             // Can't call out of the system process with a lock held, so post a message.
20132             if (app.instr.mUiAutomationConnection != null) {
20133                 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
20134                         app.instr.mUiAutomationConnection).sendToTarget();
20135             }
20136             app.instr.mFinished = true;
20137         }
20138
20139         app.instr.removeProcess(app);
20140         app.instr = null;
20141
20142         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
20143                 "finished inst");
20144     }
20145
20146     public void finishInstrumentation(IApplicationThread target,
20147             int resultCode, Bundle results) {
20148         int userId = UserHandle.getCallingUserId();
20149         // Refuse possible leaked file descriptors
20150         if (results != null && results.hasFileDescriptors()) {
20151             throw new IllegalArgumentException("File descriptors passed in Intent");
20152         }
20153
20154         synchronized(this) {
20155             ProcessRecord app = getRecordForAppLocked(target);
20156             if (app == null) {
20157                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
20158                 return;
20159             }
20160             final long origId = Binder.clearCallingIdentity();
20161             finishInstrumentationLocked(app, resultCode, results);
20162             Binder.restoreCallingIdentity(origId);
20163         }
20164     }
20165
20166     // =========================================================
20167     // CONFIGURATION
20168     // =========================================================
20169
20170     public ConfigurationInfo getDeviceConfigurationInfo() {
20171         ConfigurationInfo config = new ConfigurationInfo();
20172         synchronized (this) {
20173             final Configuration globalConfig = getGlobalConfiguration();
20174             config.reqTouchScreen = globalConfig.touchscreen;
20175             config.reqKeyboardType = globalConfig.keyboard;
20176             config.reqNavigation = globalConfig.navigation;
20177             if (globalConfig.navigation == Configuration.NAVIGATION_DPAD
20178                     || globalConfig.navigation == Configuration.NAVIGATION_TRACKBALL) {
20179                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
20180             }
20181             if (globalConfig.keyboard != Configuration.KEYBOARD_UNDEFINED
20182                     && globalConfig.keyboard != Configuration.KEYBOARD_NOKEYS) {
20183                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
20184             }
20185             config.reqGlEsVersion = GL_ES_VERSION;
20186         }
20187         return config;
20188     }
20189
20190     ActivityStack getFocusedStack() {
20191         return mStackSupervisor.getFocusedStack();
20192     }
20193
20194     @Override
20195     public int getFocusedStackId() throws RemoteException {
20196         ActivityStack focusedStack = getFocusedStack();
20197         if (focusedStack != null) {
20198             return focusedStack.getStackId();
20199         }
20200         return -1;
20201     }
20202
20203     public Configuration getConfiguration() {
20204         Configuration ci;
20205         synchronized(this) {
20206             ci = new Configuration(getGlobalConfiguration());
20207             ci.userSetLocale = false;
20208         }
20209         return ci;
20210     }
20211
20212     @Override
20213     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
20214         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
20215         synchronized (this) {
20216             mSuppressResizeConfigChanges = suppress;
20217         }
20218     }
20219
20220     /**
20221      * NOTE: For the pinned stack, this method is usually called after the bounds animation has
20222      *       animated the stack to the fullscreen, but can also be called if we are relaunching an
20223      *       activity and clearing the task at the same time.
20224      */
20225     @Override
20226     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
20227         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
20228         if (StackId.isHomeOrRecentsStack(fromStackId)) {
20229             throw new IllegalArgumentException("You can't move tasks from the home/recents stack.");
20230         }
20231         synchronized (this) {
20232             final long origId = Binder.clearCallingIdentity();
20233             try {
20234                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
20235             } finally {
20236                 Binder.restoreCallingIdentity(origId);
20237             }
20238         }
20239     }
20240
20241     @Override
20242     public void updatePersistentConfiguration(Configuration values) {
20243         enforceCallingPermission(CHANGE_CONFIGURATION, "updatePersistentConfiguration()");
20244         enforceWriteSettingsPermission("updatePersistentConfiguration()");
20245         if (values == null) {
20246             throw new NullPointerException("Configuration must not be null");
20247         }
20248
20249         int userId = UserHandle.getCallingUserId();
20250
20251         synchronized(this) {
20252             updatePersistentConfigurationLocked(values, userId);
20253         }
20254     }
20255
20256     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
20257         final long origId = Binder.clearCallingIdentity();
20258         try {
20259             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
20260         } finally {
20261             Binder.restoreCallingIdentity(origId);
20262         }
20263     }
20264
20265     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
20266         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
20267                 FONT_SCALE, 1.0f, userId);
20268
20269         synchronized (this) {
20270             if (getGlobalConfiguration().fontScale == scaleFactor) {
20271                 return;
20272             }
20273
20274             final Configuration configuration
20275                     = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20276             configuration.fontScale = scaleFactor;
20277             updatePersistentConfigurationLocked(configuration, userId);
20278         }
20279     }
20280
20281     private void enforceWriteSettingsPermission(String func) {
20282         int uid = Binder.getCallingUid();
20283         if (uid == ROOT_UID) {
20284             return;
20285         }
20286
20287         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
20288                 Settings.getPackageNameForUid(mContext, uid), false)) {
20289             return;
20290         }
20291
20292         String msg = "Permission Denial: " + func + " from pid="
20293                 + Binder.getCallingPid()
20294                 + ", uid=" + uid
20295                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
20296         Slog.w(TAG, msg);
20297         throw new SecurityException(msg);
20298     }
20299
20300     @Override
20301     public boolean updateConfiguration(Configuration values) {
20302         enforceCallingPermission(CHANGE_CONFIGURATION, "updateConfiguration()");
20303
20304         synchronized(this) {
20305             if (values == null && mWindowManager != null) {
20306                 // sentinel: fetch the current configuration from the window manager
20307                 values = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
20308             }
20309
20310             if (mWindowManager != null) {
20311                 // Update OOM levels based on display size.
20312                 mProcessList.applyDisplaySize(mWindowManager);
20313             }
20314
20315             final long origId = Binder.clearCallingIdentity();
20316             try {
20317                 if (values != null) {
20318                     Settings.System.clearConfiguration(values);
20319                 }
20320                 updateConfigurationLocked(values, null, false, false /* persistent */,
20321                         UserHandle.USER_NULL, false /* deferResume */,
20322                         mTmpUpdateConfigurationResult);
20323                 return mTmpUpdateConfigurationResult.changes != 0;
20324             } finally {
20325                 Binder.restoreCallingIdentity(origId);
20326             }
20327         }
20328     }
20329
20330     void updateUserConfigurationLocked() {
20331         final Configuration configuration = new Configuration(getGlobalConfiguration());
20332         final int currentUserId = mUserController.getCurrentUserIdLocked();
20333         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
20334                 currentUserId, Settings.System.canWrite(mContext));
20335         updateConfigurationLocked(configuration, null /* starting */, false /* initLocale */,
20336                 false /* persistent */, currentUserId, false /* deferResume */);
20337     }
20338
20339     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20340             boolean initLocale) {
20341         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
20342     }
20343
20344     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20345             boolean initLocale, boolean deferResume) {
20346         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
20347         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
20348                 UserHandle.USER_NULL, deferResume);
20349     }
20350
20351     // To cache the list of supported system locales
20352     private String[] mSupportedSystemLocales = null;
20353
20354     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20355             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
20356         return updateConfigurationLocked(values, starting, initLocale, persistent, userId,
20357                 deferResume, null /* result */);
20358     }
20359
20360     /**
20361      * Do either or both things: (1) change the current configuration, and (2)
20362      * make sure the given activity is running with the (now) current
20363      * configuration.  Returns true if the activity has been left running, or
20364      * false if <var>starting</var> is being destroyed to match the new
20365      * configuration.
20366      *
20367      * @param userId is only used when persistent parameter is set to true to persist configuration
20368      *               for that particular user
20369      */
20370     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
20371             boolean initLocale, boolean persistent, int userId, boolean deferResume,
20372             UpdateConfigurationResult result) {
20373         int changes = 0;
20374         boolean kept = true;
20375
20376         if (mWindowManager != null) {
20377             mWindowManager.deferSurfaceLayout();
20378         }
20379         try {
20380             if (values != null) {
20381                 changes = updateGlobalConfiguration(values, initLocale, persistent, userId,
20382                         deferResume);
20383             }
20384
20385             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20386         } finally {
20387             if (mWindowManager != null) {
20388                 mWindowManager.continueSurfaceLayout();
20389             }
20390         }
20391
20392         if (result != null) {
20393             result.changes = changes;
20394             result.activityRelaunched = !kept;
20395         }
20396         return kept;
20397     }
20398
20399     /** Update default (global) configuration and notify listeners about changes. */
20400     private int updateGlobalConfiguration(@NonNull Configuration values, boolean initLocale,
20401             boolean persistent, int userId, boolean deferResume) {
20402         mTempConfig.setTo(getGlobalConfiguration());
20403         final int changes = mTempConfig.updateFrom(values);
20404         if (changes == 0) {
20405             // Since calling to Activity.setRequestedOrientation leads to freezing the window with
20406             // setting WindowManagerService.mWaitingForConfig to true, it is important that we call
20407             // performDisplayOverrideConfigUpdate in order to send the new display configuration
20408             // (even if there are no actual changes) to unfreeze the window.
20409             performDisplayOverrideConfigUpdate(values, deferResume, DEFAULT_DISPLAY);
20410             return 0;
20411         }
20412
20413         if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
20414                 "Updating global configuration to: " + values);
20415
20416         EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
20417
20418         if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
20419             final LocaleList locales = values.getLocales();
20420             int bestLocaleIndex = 0;
20421             if (locales.size() > 1) {
20422                 if (mSupportedSystemLocales == null) {
20423                     mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
20424                 }
20425                 bestLocaleIndex = Math.max(0, locales.getFirstMatchIndex(mSupportedSystemLocales));
20426             }
20427             SystemProperties.set("persist.sys.locale",
20428                     locales.get(bestLocaleIndex).toLanguageTag());
20429             LocaleList.setDefault(locales, bestLocaleIndex);
20430             mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
20431                     locales.get(bestLocaleIndex)));
20432         }
20433
20434         mConfigurationSeq = Math.max(++mConfigurationSeq, 1);
20435         mTempConfig.seq = mConfigurationSeq;
20436
20437         // Update stored global config and notify everyone about the change.
20438         mStackSupervisor.onConfigurationChanged(mTempConfig);
20439
20440         Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + mTempConfig);
20441         // TODO(multi-display): Update UsageEvents#Event to include displayId.
20442         mUsageStatsService.reportConfigurationChange(mTempConfig,
20443                 mUserController.getCurrentUserIdLocked());
20444
20445         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
20446         mShowDialogs = shouldShowDialogs(mTempConfig);
20447
20448         AttributeCache ac = AttributeCache.instance();
20449         if (ac != null) {
20450             ac.updateConfiguration(mTempConfig);
20451         }
20452
20453         // Make sure all resources in our process are updated right now, so that anyone who is going
20454         // to retrieve resource values after we return will be sure to get the new ones. This is
20455         // especially important during boot, where the first config change needs to guarantee all
20456         // resources have that config before following boot code is executed.
20457         mSystemThread.applyConfigurationToResources(mTempConfig);
20458
20459         // We need another copy of global config because we're scheduling some calls instead of
20460         // running them in place. We need to be sure that object we send will be handled unchanged.
20461         final Configuration configCopy = new Configuration(mTempConfig);
20462         if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
20463             Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
20464             msg.obj = configCopy;
20465             msg.arg1 = userId;
20466             mHandler.sendMessage(msg);
20467         }
20468
20469         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20470             ProcessRecord app = mLruProcesses.get(i);
20471             try {
20472                 if (app.thread != null) {
20473                     if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
20474                             + app.processName + " new config " + configCopy);
20475                     app.thread.scheduleConfigurationChanged(configCopy);
20476                 }
20477             } catch (Exception e) {
20478             }
20479         }
20480
20481         Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
20482         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_REPLACE_PENDING
20483                 | Intent.FLAG_RECEIVER_FOREGROUND
20484                 | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20485         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20486                 AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20487                 UserHandle.USER_ALL);
20488         if ((changes & ActivityInfo.CONFIG_LOCALE) != 0) {
20489             intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
20490             intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND
20491                     | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND
20492                     | Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
20493             if (initLocale || !mProcessesReady) {
20494                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20495             }
20496             broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
20497                     AppOpsManager.OP_NONE, null, false, false, MY_PID, SYSTEM_UID,
20498                     UserHandle.USER_ALL);
20499         }
20500
20501         // Override configuration of the default display duplicates global config, so we need to
20502         // update it also. This will also notify WindowManager about changes.
20503         performDisplayOverrideConfigUpdate(mStackSupervisor.getConfiguration(), deferResume,
20504                 DEFAULT_DISPLAY);
20505
20506         return changes;
20507     }
20508
20509     @Override
20510     public boolean updateDisplayOverrideConfiguration(Configuration values, int displayId) {
20511         enforceCallingPermission(CHANGE_CONFIGURATION, "updateDisplayOverrideConfiguration()");
20512
20513         synchronized (this) {
20514             // Check if display is initialized in AM.
20515             if (!mStackSupervisor.isDisplayAdded(displayId)) {
20516                 // Call might come when display is not yet added or has already been removed.
20517                 if (DEBUG_CONFIGURATION) {
20518                     Slog.w(TAG, "Trying to update display configuration for non-existing displayId="
20519                             + displayId);
20520                 }
20521                 return false;
20522             }
20523
20524             if (values == null && mWindowManager != null) {
20525                 // sentinel: fetch the current configuration from the window manager
20526                 values = mWindowManager.computeNewConfiguration(displayId);
20527             }
20528
20529             if (mWindowManager != null) {
20530                 // Update OOM levels based on display size.
20531                 mProcessList.applyDisplaySize(mWindowManager);
20532             }
20533
20534             final long origId = Binder.clearCallingIdentity();
20535             try {
20536                 if (values != null) {
20537                     Settings.System.clearConfiguration(values);
20538                 }
20539                 updateDisplayOverrideConfigurationLocked(values, null /* starting */,
20540                         false /* deferResume */, displayId, mTmpUpdateConfigurationResult);
20541                 return mTmpUpdateConfigurationResult.changes != 0;
20542             } finally {
20543                 Binder.restoreCallingIdentity(origId);
20544             }
20545         }
20546     }
20547
20548     boolean updateDisplayOverrideConfigurationLocked(Configuration values, ActivityRecord starting,
20549             boolean deferResume, int displayId) {
20550         return updateDisplayOverrideConfigurationLocked(values, starting, deferResume /* deferResume */,
20551                 displayId, null /* result */);
20552     }
20553
20554     /**
20555      * Updates override configuration specific for the selected display. If no config is provided,
20556      * new one will be computed in WM based on current display info.
20557      */
20558     private boolean updateDisplayOverrideConfigurationLocked(Configuration values,
20559             ActivityRecord starting, boolean deferResume, int displayId,
20560             UpdateConfigurationResult result) {
20561         int changes = 0;
20562         boolean kept = true;
20563
20564         if (mWindowManager != null) {
20565             mWindowManager.deferSurfaceLayout();
20566         }
20567         try {
20568             if (values != null) {
20569                 if (displayId == DEFAULT_DISPLAY) {
20570                     // Override configuration of the default display duplicates global config, so
20571                     // we're calling global config update instead for default display. It will also
20572                     // apply the correct override config.
20573                     changes = updateGlobalConfiguration(values, false /* initLocale */,
20574                             false /* persistent */, UserHandle.USER_NULL /* userId */, deferResume);
20575                 } else {
20576                     changes = performDisplayOverrideConfigUpdate(values, deferResume, displayId);
20577                 }
20578             }
20579
20580             kept = ensureConfigAndVisibilityAfterUpdate(starting, changes);
20581         } finally {
20582             if (mWindowManager != null) {
20583                 mWindowManager.continueSurfaceLayout();
20584             }
20585         }
20586
20587         if (result != null) {
20588             result.changes = changes;
20589             result.activityRelaunched = !kept;
20590         }
20591         return kept;
20592     }
20593
20594     private int performDisplayOverrideConfigUpdate(Configuration values, boolean deferResume,
20595             int displayId) {
20596         mTempConfig.setTo(mStackSupervisor.getDisplayOverrideConfiguration(displayId));
20597         final int changes = mTempConfig.updateFrom(values);
20598         if (changes != 0) {
20599             Slog.i(TAG, "Override config changes=" + Integer.toHexString(changes) + " "
20600                     + mTempConfig + " for displayId=" + displayId);
20601             mStackSupervisor.setDisplayOverrideConfiguration(mTempConfig, displayId);
20602
20603             final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
20604             if (isDensityChange && displayId == DEFAULT_DISPLAY) {
20605                 // Reset the unsupported display size dialog.
20606                 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
20607
20608                 killAllBackgroundProcessesExcept(N,
20609                         ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
20610             }
20611         }
20612
20613         // Update the configuration with WM first and check if any of the stacks need to be resized
20614         // due to the configuration change. If so, resize the stacks now and do any relaunches if
20615         // necessary. This way we don't need to relaunch again afterwards in
20616         // ensureActivityConfigurationLocked().
20617         if (mWindowManager != null) {
20618             final int[] resizedStacks =
20619                     mWindowManager.setNewDisplayOverrideConfiguration(mTempConfig, displayId);
20620             if (resizedStacks != null) {
20621                 for (int stackId : resizedStacks) {
20622                     resizeStackWithBoundsFromWindowManager(stackId, deferResume);
20623                 }
20624             }
20625         }
20626
20627         return changes;
20628     }
20629
20630     /** Applies latest configuration and/or visibility updates if needed. */
20631     private boolean ensureConfigAndVisibilityAfterUpdate(ActivityRecord starting, int changes) {
20632         boolean kept = true;
20633         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
20634         // mainStack is null during startup.
20635         if (mainStack != null) {
20636             if (changes != 0 && starting == null) {
20637                 // If the configuration changed, and the caller is not already
20638                 // in the process of starting an activity, then find the top
20639                 // activity to check if its configuration needs to change.
20640                 starting = mainStack.topRunningActivityLocked();
20641             }
20642
20643             if (starting != null) {
20644                 kept = starting.ensureActivityConfigurationLocked(changes,
20645                         false /* preserveWindow */);
20646                 // And we need to make sure at this point that all other activities
20647                 // are made visible with the correct configuration.
20648                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
20649                         !PRESERVE_WINDOWS);
20650             }
20651         }
20652
20653         return kept;
20654     }
20655
20656     /** Helper method that requests bounds from WM and applies them to stack. */
20657     private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
20658         final Rect newStackBounds = new Rect();
20659         mStackSupervisor.getStack(stackId).getBoundsForNewConfiguration(newStackBounds);
20660         mStackSupervisor.resizeStackLocked(
20661                 stackId, !newStackBounds.isEmpty() ? newStackBounds : null /* bounds */,
20662                 null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
20663                 false /* preserveWindows */, false /* allowResizeInDockedMode */, deferResume);
20664     }
20665
20666     /**
20667      * Decide based on the configuration whether we should show the ANR,
20668      * crash, etc dialogs.  The idea is that if there is no affordance to
20669      * press the on-screen buttons, or the user experience would be more
20670      * greatly impacted than the crash itself, we shouldn't show the dialog.
20671      *
20672      * A thought: SystemUI might also want to get told about this, the Power
20673      * dialog / global actions also might want different behaviors.
20674      */
20675     private static boolean shouldShowDialogs(Configuration config) {
20676         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
20677                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
20678                                    && config.navigation == Configuration.NAVIGATION_NONAV);
20679         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
20680         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
20681                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
20682                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
20683                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
20684         return inputMethodExists && uiModeSupportsDialogs;
20685     }
20686
20687     @Override
20688     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
20689         synchronized (this) {
20690             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
20691             if (srec != null) {
20692                 return srec.getStack().shouldUpRecreateTaskLocked(srec, destAffinity);
20693             }
20694         }
20695         return false;
20696     }
20697
20698     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
20699             Intent resultData) {
20700
20701         synchronized (this) {
20702             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
20703             if (r != null) {
20704                 return r.getStack().navigateUpToLocked(r, destIntent, resultCode, resultData);
20705             }
20706             return false;
20707         }
20708     }
20709
20710     public int getLaunchedFromUid(IBinder activityToken) {
20711         ActivityRecord srec;
20712         synchronized (this) {
20713             srec = ActivityRecord.forTokenLocked(activityToken);
20714         }
20715         if (srec == null) {
20716             return -1;
20717         }
20718         return srec.launchedFromUid;
20719     }
20720
20721     public String getLaunchedFromPackage(IBinder activityToken) {
20722         ActivityRecord srec;
20723         synchronized (this) {
20724             srec = ActivityRecord.forTokenLocked(activityToken);
20725         }
20726         if (srec == null) {
20727             return null;
20728         }
20729         return srec.launchedFromPackage;
20730     }
20731
20732     // =========================================================
20733     // LIFETIME MANAGEMENT
20734     // =========================================================
20735
20736     // Returns whether the app is receiving broadcast.
20737     // If receiving, fetch all broadcast queues which the app is
20738     // the current [or imminent] receiver on.
20739     private boolean isReceivingBroadcastLocked(ProcessRecord app,
20740             ArraySet<BroadcastQueue> receivingQueues) {
20741         if (!app.curReceivers.isEmpty()) {
20742             for (BroadcastRecord r : app.curReceivers) {
20743                 receivingQueues.add(r.queue);
20744             }
20745             return true;
20746         }
20747
20748         // It's not the current receiver, but it might be starting up to become one
20749         for (BroadcastQueue queue : mBroadcastQueues) {
20750             final BroadcastRecord r = queue.mPendingBroadcast;
20751             if (r != null && r.curApp == app) {
20752                 // found it; report which queue it's in
20753                 receivingQueues.add(queue);
20754             }
20755         }
20756
20757         return !receivingQueues.isEmpty();
20758     }
20759
20760     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
20761             int targetUid, ComponentName targetComponent, String targetProcess) {
20762         if (!mTrackingAssociations) {
20763             return null;
20764         }
20765         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20766                 = mAssociations.get(targetUid);
20767         if (components == null) {
20768             components = new ArrayMap<>();
20769             mAssociations.put(targetUid, components);
20770         }
20771         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20772         if (sourceUids == null) {
20773             sourceUids = new SparseArray<>();
20774             components.put(targetComponent, sourceUids);
20775         }
20776         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20777         if (sourceProcesses == null) {
20778             sourceProcesses = new ArrayMap<>();
20779             sourceUids.put(sourceUid, sourceProcesses);
20780         }
20781         Association ass = sourceProcesses.get(sourceProcess);
20782         if (ass == null) {
20783             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
20784                     targetProcess);
20785             sourceProcesses.put(sourceProcess, ass);
20786         }
20787         ass.mCount++;
20788         ass.mNesting++;
20789         if (ass.mNesting == 1) {
20790             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
20791             ass.mLastState = sourceState;
20792         }
20793         return ass;
20794     }
20795
20796     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
20797             ComponentName targetComponent) {
20798         if (!mTrackingAssociations) {
20799             return;
20800         }
20801         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
20802                 = mAssociations.get(targetUid);
20803         if (components == null) {
20804             return;
20805         }
20806         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
20807         if (sourceUids == null) {
20808             return;
20809         }
20810         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
20811         if (sourceProcesses == null) {
20812             return;
20813         }
20814         Association ass = sourceProcesses.get(sourceProcess);
20815         if (ass == null || ass.mNesting <= 0) {
20816             return;
20817         }
20818         ass.mNesting--;
20819         if (ass.mNesting == 0) {
20820             long uptime = SystemClock.uptimeMillis();
20821             ass.mTime += uptime - ass.mStartTime;
20822             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20823                     += uptime - ass.mLastStateUptime;
20824             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
20825         }
20826     }
20827
20828     private void noteUidProcessState(final int uid, final int state) {
20829         mBatteryStatsService.noteUidProcessState(uid, state);
20830         if (mTrackingAssociations) {
20831             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
20832                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
20833                         = mAssociations.valueAt(i1);
20834                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
20835                     SparseArray<ArrayMap<String, Association>> sourceUids
20836                             = targetComponents.valueAt(i2);
20837                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
20838                     if (sourceProcesses != null) {
20839                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
20840                             Association ass = sourceProcesses.valueAt(i4);
20841                             if (ass.mNesting >= 1) {
20842                                 // currently associated
20843                                 long uptime = SystemClock.uptimeMillis();
20844                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
20845                                         += uptime - ass.mLastStateUptime;
20846                                 ass.mLastState = state;
20847                                 ass.mLastStateUptime = uptime;
20848                             }
20849                         }
20850                     }
20851                 }
20852             }
20853         }
20854     }
20855
20856     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
20857             boolean doingAll, long now) {
20858         if (mAdjSeq == app.adjSeq) {
20859             // This adjustment has already been computed.
20860             return app.curRawAdj;
20861         }
20862
20863         if (app.thread == null) {
20864             app.adjSeq = mAdjSeq;
20865             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20866             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20867             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
20868         }
20869
20870         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
20871         app.adjSource = null;
20872         app.adjTarget = null;
20873         app.empty = false;
20874         app.cached = false;
20875
20876         final int activitiesSize = app.activities.size();
20877
20878         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
20879             // The max adjustment doesn't allow this app to be anything
20880             // below foreground, so it is not worth doing work for it.
20881             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making fixed: " + app);
20882             app.adjType = "fixed";
20883             app.adjSeq = mAdjSeq;
20884             app.curRawAdj = app.maxAdj;
20885             app.foregroundActivities = false;
20886             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20887             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
20888             // System processes can do UI, and when they do we want to have
20889             // them trim their memory after the user leaves the UI.  To
20890             // facilitate this, here we need to determine whether or not it
20891             // is currently showing UI.
20892             app.systemNoUi = true;
20893             if (app == TOP_APP) {
20894                 app.systemNoUi = false;
20895                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20896                 app.adjType = "pers-top-activity";
20897             } else if (app.hasTopUi) {
20898                 app.systemNoUi = false;
20899                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20900                 app.adjType = "pers-top-ui";
20901             } else if (activitiesSize > 0) {
20902                 for (int j = 0; j < activitiesSize; j++) {
20903                     final ActivityRecord r = app.activities.get(j);
20904                     if (r.visible) {
20905                         app.systemNoUi = false;
20906                     }
20907                 }
20908             }
20909             if (!app.systemNoUi) {
20910                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
20911             }
20912             return (app.curAdj=app.maxAdj);
20913         }
20914
20915         app.systemNoUi = false;
20916
20917         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
20918
20919         // Determine the importance of the process, starting with most
20920         // important to least, and assign an appropriate OOM adjustment.
20921         int adj;
20922         int schedGroup;
20923         int procState;
20924         boolean foregroundActivities = false;
20925         mTmpBroadcastQueue.clear();
20926         if (app == TOP_APP) {
20927             // The last app on the list is the foreground app.
20928             adj = ProcessList.FOREGROUND_APP_ADJ;
20929             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
20930             app.adjType = "top-activity";
20931             foregroundActivities = true;
20932             procState = PROCESS_STATE_CUR_TOP;
20933             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making top: " + app);
20934         } else if (app.instr != null) {
20935             // Don't want to kill running instrumentation.
20936             adj = ProcessList.FOREGROUND_APP_ADJ;
20937             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20938             app.adjType = "instrumentation";
20939             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
20940             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making instrumentation: " + app);
20941         } else if (isReceivingBroadcastLocked(app, mTmpBroadcastQueue)) {
20942             // An app that is currently receiving a broadcast also
20943             // counts as being in the foreground for OOM killer purposes.
20944             // It's placed in a sched group based on the nature of the
20945             // broadcast as reflected by which queue it's active in.
20946             adj = ProcessList.FOREGROUND_APP_ADJ;
20947             schedGroup = (mTmpBroadcastQueue.contains(mFgBroadcastQueue))
20948                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20949             app.adjType = "broadcast";
20950             procState = ActivityManager.PROCESS_STATE_RECEIVER;
20951             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making broadcast: " + app);
20952         } else if (app.executingServices.size() > 0) {
20953             // An app that is currently executing a service callback also
20954             // counts as being in the foreground.
20955             adj = ProcessList.FOREGROUND_APP_ADJ;
20956             schedGroup = app.execServicesFg ?
20957                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
20958             app.adjType = "exec-service";
20959             procState = ActivityManager.PROCESS_STATE_SERVICE;
20960             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making exec-service: " + app);
20961             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
20962         } else {
20963             // As far as we know the process is empty.  We may change our mind later.
20964             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
20965             // At this point we don't actually know the adjustment.  Use the cached adj
20966             // value that the caller wants us to.
20967             adj = cachedAdj;
20968             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
20969             app.cached = true;
20970             app.empty = true;
20971             app.adjType = "cch-empty";
20972             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Making empty: " + app);
20973         }
20974
20975         // Examine all activities if not already foreground.
20976         if (!foregroundActivities && activitiesSize > 0) {
20977             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
20978             for (int j = 0; j < activitiesSize; j++) {
20979                 final ActivityRecord r = app.activities.get(j);
20980                 if (r.app != app) {
20981                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
20982                             + " instead of expected " + app);
20983                     if (r.app == null || (r.app.uid == app.uid)) {
20984                         // Only fix things up when they look sane
20985                         r.app = app;
20986                     } else {
20987                         continue;
20988                     }
20989                 }
20990                 if (r.visible) {
20991                     // App has a visible activity; only upgrade adjustment.
20992                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
20993                         adj = ProcessList.VISIBLE_APP_ADJ;
20994                         app.adjType = "vis-activity";
20995                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
20996                     }
20997                     if (procState > PROCESS_STATE_CUR_TOP) {
20998                         procState = PROCESS_STATE_CUR_TOP;
20999                         app.adjType = "vis-activity";
21000                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to vis-activity: " + app);
21001                     }
21002                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21003                     app.cached = false;
21004                     app.empty = false;
21005                     foregroundActivities = true;
21006                     final TaskRecord task = r.getTask();
21007                     if (task != null && minLayer > 0) {
21008                         final int layer = task.mLayerRank;
21009                         if (layer >= 0 && minLayer > layer) {
21010                             minLayer = layer;
21011                         }
21012                     }
21013                     break;
21014                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
21015                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21016                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21017                         app.adjType = "pause-activity";
21018                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21019                     }
21020                     if (procState > PROCESS_STATE_CUR_TOP) {
21021                         procState = PROCESS_STATE_CUR_TOP;
21022                         app.adjType = "pause-activity";
21023                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to pause-activity: " + app);
21024                     }
21025                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21026                     app.cached = false;
21027                     app.empty = false;
21028                     foregroundActivities = true;
21029                 } else if (r.state == ActivityState.STOPPING) {
21030                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21031                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21032                         app.adjType = "stop-activity";
21033                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21034                     }
21035                     // For the process state, we will at this point consider the
21036                     // process to be cached.  It will be cached either as an activity
21037                     // or empty depending on whether the activity is finishing.  We do
21038                     // this so that we can treat the process as cached for purposes of
21039                     // memory trimming (determing current memory level, trim command to
21040                     // send to process) since there can be an arbitrary number of stopping
21041                     // processes and they should soon all go into the cached state.
21042                     if (!r.finishing) {
21043                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21044                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21045                             app.adjType = "stop-activity";
21046                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to stop-activity: " + app);
21047                         }
21048                     }
21049                     app.cached = false;
21050                     app.empty = false;
21051                     foregroundActivities = true;
21052                 } else {
21053                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21054                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21055                         app.adjType = "cch-act";
21056                         if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to cached activity: " + app);
21057                     }
21058                 }
21059             }
21060             if (adj == ProcessList.VISIBLE_APP_ADJ) {
21061                 adj += minLayer;
21062             }
21063         }
21064
21065         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21066                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
21067             if (app.foregroundServices) {
21068                 // The user is aware of this app, so make it visible.
21069                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21070                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
21071                 app.cached = false;
21072                 app.adjType = "fg-service";
21073                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21074                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to fg service: " + app);
21075             } else if (app.hasOverlayUi) {
21076                 // The process is display an overlay UI.
21077                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21078                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21079                 app.cached = false;
21080                 app.adjType = "has-overlay-ui";
21081                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21082                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to overlay ui: " + app);
21083             }
21084         }
21085
21086         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
21087                 || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21088             if (app.forcingToImportant != null) {
21089                 // This is currently used for toasts...  they are not interactive, and
21090                 // we don't want them to cause the app to become fully foreground (and
21091                 // thus out of background check), so we yes the best background level we can.
21092                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
21093                 procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21094                 app.cached = false;
21095                 app.adjType = "force-imp";
21096                 app.adjSource = app.forcingToImportant;
21097                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21098                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to force imp: " + app);
21099             }
21100         }
21101
21102         if (app == mHeavyWeightProcess) {
21103             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
21104                 // We don't want to kill the current heavy-weight process.
21105                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
21106                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21107                 app.cached = false;
21108                 app.adjType = "heavy";
21109                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21110             }
21111             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21112                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
21113                 app.adjType = "heavy";
21114                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to heavy: " + app);
21115             }
21116         }
21117
21118         if (app == mHomeProcess) {
21119             if (adj > ProcessList.HOME_APP_ADJ) {
21120                 // This process is hosting what we currently consider to be the
21121                 // home app, so we don't want to let it go into the background.
21122                 adj = ProcessList.HOME_APP_ADJ;
21123                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21124                 app.cached = false;
21125                 app.adjType = "home";
21126                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21127             }
21128             if (procState > ActivityManager.PROCESS_STATE_HOME) {
21129                 procState = ActivityManager.PROCESS_STATE_HOME;
21130                 app.adjType = "home";
21131                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to home: " + app);
21132             }
21133         }
21134
21135         if (app == mPreviousProcess && app.activities.size() > 0) {
21136             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21137                 // This was the previous process that showed UI to the user.
21138                 // We want to try to keep it around more aggressively, to give
21139                 // a good experience around switching between two apps.
21140                 adj = ProcessList.PREVIOUS_APP_ADJ;
21141                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21142                 app.cached = false;
21143                 app.adjType = "previous";
21144                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21145             }
21146             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21147                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21148                 app.adjType = "previous";
21149                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to prev: " + app);
21150             }
21151         }
21152
21153         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
21154                 + " reason=" + app.adjType);
21155
21156         // By default, we use the computed adjustment.  It may be changed if
21157         // there are applications dependent on our services or providers, but
21158         // this gives us a baseline and makes sure we don't get into an
21159         // infinite recursion.
21160         app.adjSeq = mAdjSeq;
21161         app.curRawAdj = adj;
21162         app.hasStartedServices = false;
21163
21164         if (mBackupTarget != null && app == mBackupTarget.app) {
21165             // If possible we want to avoid killing apps while they're being backed up
21166             if (adj > ProcessList.BACKUP_APP_ADJ) {
21167                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
21168                 adj = ProcessList.BACKUP_APP_ADJ;
21169                 if (procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21170                     procState = ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21171                 }
21172                 app.adjType = "backup";
21173                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21174                 app.cached = false;
21175             }
21176             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
21177                 procState = ActivityManager.PROCESS_STATE_BACKUP;
21178                 app.adjType = "backup";
21179                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to backup: " + app);
21180             }
21181         }
21182
21183         boolean mayBeTop = false;
21184         String mayBeTopType = null;
21185         Object mayBeTopSource = null;
21186         Object mayBeTopTarget = null;
21187
21188         for (int is = app.services.size()-1;
21189                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21190                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21191                         || procState > ActivityManager.PROCESS_STATE_TOP);
21192                 is--) {
21193             ServiceRecord s = app.services.valueAt(is);
21194             if (s.startRequested) {
21195                 app.hasStartedServices = true;
21196                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
21197                     procState = ActivityManager.PROCESS_STATE_SERVICE;
21198                     app.adjType = "started-services";
21199                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21200                 }
21201                 if (app.hasShownUi && app != mHomeProcess) {
21202                     // If this process has shown some UI, let it immediately
21203                     // go to the LRU list because it may be pretty heavy with
21204                     // UI stuff.  We'll tag it with a label just to help
21205                     // debug and understand what is going on.
21206                     if (adj > ProcessList.SERVICE_ADJ) {
21207                         app.adjType = "cch-started-ui-services";
21208                     }
21209                 } else {
21210                     if (now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21211                         // This service has seen some activity within
21212                         // recent memory, so we will keep its process ahead
21213                         // of the background processes.
21214                         if (adj > ProcessList.SERVICE_ADJ) {
21215                             adj = ProcessList.SERVICE_ADJ;
21216                             app.adjType = "started-services";
21217                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to started service: " + app);
21218                             app.cached = false;
21219                         }
21220                     }
21221                     // If we have let the service slide into the background
21222                     // state, still have some text describing what it is doing
21223                     // even though the service no longer has an impact.
21224                     if (adj > ProcessList.SERVICE_ADJ) {
21225                         app.adjType = "cch-started-services";
21226                     }
21227                 }
21228             }
21229
21230             for (int conni = s.connections.size()-1;
21231                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21232                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21233                             || procState > ActivityManager.PROCESS_STATE_TOP);
21234                     conni--) {
21235                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
21236                 for (int i = 0;
21237                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
21238                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21239                                 || procState > ActivityManager.PROCESS_STATE_TOP);
21240                         i++) {
21241                     // XXX should compute this based on the max of
21242                     // all connected clients.
21243                     ConnectionRecord cr = clist.get(i);
21244                     if (cr.binding.client == app) {
21245                         // Binding to ourself is not interesting.
21246                         continue;
21247                     }
21248
21249                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
21250                         ProcessRecord client = cr.binding.client;
21251                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
21252                                 TOP_APP, doingAll, now);
21253                         int clientProcState = client.curProcState;
21254                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21255                             // If the other app is cached for any reason, for purposes here
21256                             // we are going to consider it empty.  The specific cached state
21257                             // doesn't propagate except under certain conditions.
21258                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21259                         }
21260                         String adjType = null;
21261                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
21262                             // Not doing bind OOM management, so treat
21263                             // this guy more like a started service.
21264                             if (app.hasShownUi && app != mHomeProcess) {
21265                                 // If this process has shown some UI, let it immediately
21266                                 // go to the LRU list because it may be pretty heavy with
21267                                 // UI stuff.  We'll tag it with a label just to help
21268                                 // debug and understand what is going on.
21269                                 if (adj > clientAdj) {
21270                                     adjType = "cch-bound-ui-services";
21271                                 }
21272                                 app.cached = false;
21273                                 clientAdj = adj;
21274                                 clientProcState = procState;
21275                             } else {
21276                                 if (now >= (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) {
21277                                     // This service has not seen activity within
21278                                     // recent memory, so allow it to drop to the
21279                                     // LRU list if there is no other reason to keep
21280                                     // it around.  We'll also tag it with a label just
21281                                     // to help debug and undertand what is going on.
21282                                     if (adj > clientAdj) {
21283                                         adjType = "cch-bound-services";
21284                                     }
21285                                     clientAdj = adj;
21286                                 }
21287                             }
21288                         }
21289                         if (adj > clientAdj) {
21290                             // If this process has recently shown UI, and
21291                             // the process that is binding to it is less
21292                             // important than being visible, then we don't
21293                             // care about the binding as much as we care
21294                             // about letting this process get into the LRU
21295                             // list to be killed and restarted if needed for
21296                             // memory.
21297                             if (app.hasShownUi && app != mHomeProcess
21298                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21299                                 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
21300                                     adjType = "cch-bound-ui-services";
21301                                 }
21302                             } else {
21303                                 int newAdj;
21304                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
21305                                         |Context.BIND_IMPORTANT)) != 0) {
21306                                     newAdj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
21307                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
21308                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
21309                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
21310                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21311                                     newAdj = ProcessList.PERCEPTIBLE_APP_ADJ;
21312                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
21313                                     newAdj = clientAdj;
21314                                 } else {
21315                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
21316                                         newAdj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
21317                                     } else {
21318                                         newAdj = adj;
21319                                     }
21320                                 }
21321                                 if (!client.cached) {
21322                                     app.cached = false;
21323                                 }
21324                                 if (adj >  newAdj) {
21325                                     adj = newAdj;
21326                                     adjType = "service";
21327                                 }
21328                             }
21329                         }
21330                         if ((cr.flags & (Context.BIND_NOT_FOREGROUND
21331                                 | Context.BIND_IMPORTANT_BACKGROUND)) == 0) {
21332                             // This will treat important bound services identically to
21333                             // the top app, which may behave differently than generic
21334                             // foreground work.
21335                             if (client.curSchedGroup > schedGroup) {
21336                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21337                                     schedGroup = client.curSchedGroup;
21338                                 } else {
21339                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21340                                 }
21341                             }
21342                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21343                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21344                                     // Special handling of clients who are in the top state.
21345                                     // We *may* want to consider this process to be in the
21346                                     // top state as well, but only if there is not another
21347                                     // reason for it to be running.  Being on the top is a
21348                                     // special state, meaning you are specifically running
21349                                     // for the current top app.  If the process is already
21350                                     // running in the background for some other reason, it
21351                                     // is more important to continue considering it to be
21352                                     // in the background state.
21353                                     mayBeTop = true;
21354                                     mayBeTopType = "service";
21355                                     mayBeTopSource = cr.binding.client;
21356                                     mayBeTopTarget = s.name;
21357                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21358                                 } else {
21359                                     // Special handling for above-top states (persistent
21360                                     // processes).  These should not bring the current process
21361                                     // into the top state, since they are not on top.  Instead
21362                                     // give them the best state after that.
21363                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
21364                                         clientProcState =
21365                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21366                                     } else if (mWakefulness
21367                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
21368                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
21369                                                     != 0) {
21370                                         clientProcState =
21371                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21372                                     } else {
21373                                         clientProcState =
21374                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21375                                     }
21376                                 }
21377                             }
21378                         } else if ((cr.flags & Context.BIND_IMPORTANT_BACKGROUND) == 0) {
21379                             if (clientProcState <
21380                                     ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) {
21381                                 clientProcState =
21382                                         ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND;
21383                             }
21384                         } else {
21385                             if (clientProcState <
21386                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
21387                                 clientProcState =
21388                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
21389                             }
21390                         }
21391                         if (procState > clientProcState) {
21392                             procState = clientProcState;
21393                             if (adjType == null) {
21394                                 adjType = "service";
21395                             }
21396                         }
21397                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21398                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
21399                             app.pendingUiClean = true;
21400                         }
21401                         if (adjType != null) {
21402                             app.adjType = adjType;
21403                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21404                                     .REASON_SERVICE_IN_USE;
21405                             app.adjSource = cr.binding.client;
21406                             app.adjSourceProcState = clientProcState;
21407                             app.adjTarget = s.name;
21408                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21409                                     + ": " + app + ", due to " + cr.binding.client
21410                                     + " adj=" + adj + " procState=" + procState);
21411                         }
21412                     }
21413                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
21414                         app.treatLikeActivity = true;
21415                     }
21416                     final ActivityRecord a = cr.activity;
21417                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
21418                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
21419                             (a.visible || a.state == ActivityState.RESUMED ||
21420                              a.state == ActivityState.PAUSING)) {
21421                             adj = ProcessList.FOREGROUND_APP_ADJ;
21422                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
21423                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
21424                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
21425                                 } else {
21426                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21427                                 }
21428                             }
21429                             app.cached = false;
21430                             app.adjType = "service";
21431                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21432                                     .REASON_SERVICE_IN_USE;
21433                             app.adjSource = a;
21434                             app.adjSourceProcState = procState;
21435                             app.adjTarget = s.name;
21436                             if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to service w/activity: "
21437                                     + app);
21438                         }
21439                     }
21440                 }
21441             }
21442         }
21443
21444         for (int provi = app.pubProviders.size()-1;
21445                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21446                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21447                         || procState > ActivityManager.PROCESS_STATE_TOP);
21448                 provi--) {
21449             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
21450             for (int i = cpr.connections.size()-1;
21451                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
21452                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
21453                             || procState > ActivityManager.PROCESS_STATE_TOP);
21454                     i--) {
21455                 ContentProviderConnection conn = cpr.connections.get(i);
21456                 ProcessRecord client = conn.client;
21457                 if (client == app) {
21458                     // Being our own client is not interesting.
21459                     continue;
21460                 }
21461                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
21462                 int clientProcState = client.curProcState;
21463                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
21464                     // If the other app is cached for any reason, for purposes here
21465                     // we are going to consider it empty.
21466                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21467                 }
21468                 String adjType = null;
21469                 if (adj > clientAdj) {
21470                     if (app.hasShownUi && app != mHomeProcess
21471                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
21472                         adjType = "cch-ui-provider";
21473                     } else {
21474                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
21475                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
21476                         adjType = "provider";
21477                     }
21478                     app.cached &= client.cached;
21479                 }
21480                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
21481                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
21482                         // Special handling of clients who are in the top state.
21483                         // We *may* want to consider this process to be in the
21484                         // top state as well, but only if there is not another
21485                         // reason for it to be running.  Being on the top is a
21486                         // special state, meaning you are specifically running
21487                         // for the current top app.  If the process is already
21488                         // running in the background for some other reason, it
21489                         // is more important to continue considering it to be
21490                         // in the background state.
21491                         mayBeTop = true;
21492                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
21493                         mayBeTopType = adjType = "provider-top";
21494                         mayBeTopSource = client;
21495                         mayBeTopTarget = cpr.name;
21496                     } else {
21497                         // Special handling for above-top states (persistent
21498                         // processes).  These should not bring the current process
21499                         // into the top state, since they are not on top.  Instead
21500                         // give them the best state after that.
21501                         clientProcState =
21502                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21503                         if (adjType == null) {
21504                             adjType = "provider";
21505                         }
21506                     }
21507                 }
21508                 if (procState > clientProcState) {
21509                     procState = clientProcState;
21510                 }
21511                 if (client.curSchedGroup > schedGroup) {
21512                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21513                 }
21514                 if (adjType != null) {
21515                     app.adjType = adjType;
21516                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
21517                             .REASON_PROVIDER_IN_USE;
21518                     app.adjSource = client;
21519                     app.adjSourceProcState = clientProcState;
21520                     app.adjTarget = cpr.name;
21521                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to " + adjType
21522                             + ": " + app + ", due to " + client
21523                             + " adj=" + adj + " procState=" + procState);
21524                 }
21525             }
21526             // If the provider has external (non-framework) process
21527             // dependencies, ensure that its adjustment is at least
21528             // FOREGROUND_APP_ADJ.
21529             if (cpr.hasExternalProcessHandles()) {
21530                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
21531                     adj = ProcessList.FOREGROUND_APP_ADJ;
21532                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21533                     app.cached = false;
21534                     app.adjType = "ext-provider";
21535                     app.adjTarget = cpr.name;
21536                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to external provider: " + app);
21537                 }
21538                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
21539                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
21540                 }
21541             }
21542         }
21543
21544         if (app.lastProviderTime > 0 &&
21545                 (app.lastProviderTime+mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) {
21546             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
21547                 adj = ProcessList.PREVIOUS_APP_ADJ;
21548                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
21549                 app.cached = false;
21550                 app.adjType = "recent-provider";
21551                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21552             }
21553             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
21554                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
21555                 app.adjType = "recent-provider";
21556                 if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "Raise to recent provider: " + app);
21557             }
21558         }
21559
21560         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
21561             // A client of one of our services or providers is in the top state.  We
21562             // *may* want to be in the top state, but not if we are already running in
21563             // the background for some other reason.  For the decision here, we are going
21564             // to pick out a few specific states that we want to remain in when a client
21565             // is top (states that tend to be longer-term) and otherwise allow it to go
21566             // to the top state.
21567             switch (procState) {
21568                 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE:
21569                     // Something else is keeping it at this level, just leave it.
21570                     break;
21571                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
21572                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
21573                 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND:
21574                 case ActivityManager.PROCESS_STATE_SERVICE:
21575                     // These all are longer-term states, so pull them up to the top
21576                     // of the background states, but not all the way to the top state.
21577                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
21578                     app.adjType = mayBeTopType;
21579                     app.adjSource = mayBeTopSource;
21580                     app.adjTarget = mayBeTopTarget;
21581                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21582                             + ": " + app + ", due to " + mayBeTopSource
21583                             + " adj=" + adj + " procState=" + procState);
21584                     break;
21585                 default:
21586                     // Otherwise, top is a better choice, so take it.
21587                     procState = ActivityManager.PROCESS_STATE_TOP;
21588                     app.adjType = mayBeTopType;
21589                     app.adjSource = mayBeTopSource;
21590                     app.adjTarget = mayBeTopTarget;
21591                     if (DEBUG_OOM_ADJ_REASON) Slog.d(TAG, "May be top raise to " + mayBeTopType
21592                             + ": " + app + ", due to " + mayBeTopSource
21593                             + " adj=" + adj + " procState=" + procState);
21594                     break;
21595             }
21596         }
21597
21598         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
21599             if (app.hasClientActivities) {
21600                 // This is a cached process, but with client activities.  Mark it so.
21601                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
21602                 app.adjType = "cch-client-act";
21603             } else if (app.treatLikeActivity) {
21604                 // This is a cached process, but somebody wants us to treat it like it has
21605                 // an activity, okay!
21606                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
21607                 app.adjType = "cch-as-act";
21608             }
21609         }
21610
21611         if (adj == ProcessList.SERVICE_ADJ) {
21612             if (doingAll) {
21613                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
21614                 mNewNumServiceProcs++;
21615                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
21616                 if (!app.serviceb) {
21617                     // This service isn't far enough down on the LRU list to
21618                     // normally be a B service, but if we are low on RAM and it
21619                     // is large we want to force it down since we would prefer to
21620                     // keep launcher over it.
21621                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
21622                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
21623                         app.serviceHighRam = true;
21624                         app.serviceb = true;
21625                         //Slog.i(TAG, "ADJ " + app + " high ram!");
21626                     } else {
21627                         mNewNumAServiceProcs++;
21628                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
21629                     }
21630                 } else {
21631                     app.serviceHighRam = false;
21632                 }
21633             }
21634             if (app.serviceb) {
21635                 adj = ProcessList.SERVICE_B_ADJ;
21636             }
21637         }
21638
21639         app.curRawAdj = adj;
21640
21641         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
21642         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
21643         if (adj > app.maxAdj) {
21644             adj = app.maxAdj;
21645             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
21646                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
21647             }
21648         }
21649
21650         // Do final modification to adj.  Everything we do between here and applying
21651         // the final setAdj must be done in this function, because we will also use
21652         // it when computing the final cached adj later.  Note that we don't need to
21653         // worry about this for max adj above, since max adj will always be used to
21654         // keep it out of the cached vaues.
21655         app.curAdj = app.modifyRawOomAdj(adj);
21656         app.curSchedGroup = schedGroup;
21657         app.curProcState = procState;
21658         app.foregroundActivities = foregroundActivities;
21659
21660         return app.curRawAdj;
21661     }
21662
21663     /**
21664      * Record new PSS sample for a process.
21665      */
21666     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
21667             long now) {
21668         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
21669                 swapPss * 1024);
21670         proc.lastPssTime = now;
21671         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
21672         if (DEBUG_PSS) Slog.d(TAG_PSS,
21673                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
21674                 + " state=" + ProcessList.makeProcStateString(procState));
21675         if (proc.initialIdlePss == 0) {
21676             proc.initialIdlePss = pss;
21677         }
21678         proc.lastPss = pss;
21679         proc.lastSwapPss = swapPss;
21680         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
21681             proc.lastCachedPss = pss;
21682             proc.lastCachedSwapPss = swapPss;
21683         }
21684
21685         final SparseArray<Pair<Long, String>> watchUids
21686                 = mMemWatchProcesses.getMap().get(proc.processName);
21687         Long check = null;
21688         if (watchUids != null) {
21689             Pair<Long, String> val = watchUids.get(proc.uid);
21690             if (val == null) {
21691                 val = watchUids.get(0);
21692             }
21693             if (val != null) {
21694                 check = val.first;
21695             }
21696         }
21697         if (check != null) {
21698             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
21699                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21700                 if (!isDebuggable) {
21701                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
21702                         isDebuggable = true;
21703                     }
21704                 }
21705                 if (isDebuggable) {
21706                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
21707                     final ProcessRecord myProc = proc;
21708                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
21709                     mMemWatchDumpProcName = proc.processName;
21710                     mMemWatchDumpFile = heapdumpFile.toString();
21711                     mMemWatchDumpPid = proc.pid;
21712                     mMemWatchDumpUid = proc.uid;
21713                     BackgroundThread.getHandler().post(new Runnable() {
21714                         @Override
21715                         public void run() {
21716                             revokeUriPermission(ActivityThread.currentActivityThread()
21717                                             .getApplicationThread(),
21718                                     null, DumpHeapActivity.JAVA_URI,
21719                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
21720                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
21721                                     UserHandle.myUserId());
21722                             ParcelFileDescriptor fd = null;
21723                             try {
21724                                 heapdumpFile.delete();
21725                                 fd = ParcelFileDescriptor.open(heapdumpFile,
21726                                         ParcelFileDescriptor.MODE_CREATE |
21727                                                 ParcelFileDescriptor.MODE_TRUNCATE |
21728                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
21729                                                 ParcelFileDescriptor.MODE_APPEND);
21730                                 IApplicationThread thread = myProc.thread;
21731                                 if (thread != null) {
21732                                     try {
21733                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
21734                                                 "Requesting dump heap from "
21735                                                 + myProc + " to " + heapdumpFile);
21736                                         thread.dumpHeap(/* managed= */ true,
21737                                                 /* mallocInfo= */ false, /* runGc= */ false,
21738                                                 heapdumpFile.toString(), fd);
21739                                     } catch (RemoteException e) {
21740                                     }
21741                                 }
21742                             } catch (FileNotFoundException e) {
21743                                 e.printStackTrace();
21744                             } finally {
21745                                 if (fd != null) {
21746                                     try {
21747                                         fd.close();
21748                                     } catch (IOException e) {
21749                                     }
21750                                 }
21751                             }
21752                         }
21753                     });
21754                 } else {
21755                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
21756                             + ", but debugging not enabled");
21757                 }
21758             }
21759         }
21760     }
21761
21762     /**
21763      * Schedule PSS collection of a process.
21764      */
21765     void requestPssLocked(ProcessRecord proc, int procState) {
21766         if (mPendingPssProcesses.contains(proc)) {
21767             return;
21768         }
21769         if (mPendingPssProcesses.size() == 0) {
21770             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21771         }
21772         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
21773         proc.pssProcState = procState;
21774         mPendingPssProcesses.add(proc);
21775     }
21776
21777     /**
21778      * Schedule PSS collection of all processes.
21779      */
21780     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
21781         if (!always) {
21782             if (now < (mLastFullPssTime +
21783                     (memLowered ? mConstants.FULL_PSS_LOWERED_INTERVAL
21784                             : mConstants.FULL_PSS_MIN_INTERVAL))) {
21785                 return;
21786             }
21787         }
21788         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
21789         mLastFullPssTime = now;
21790         mFullPssPending = true;
21791         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
21792         mPendingPssProcesses.clear();
21793         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21794             ProcessRecord app = mLruProcesses.get(i);
21795             if (app.thread == null
21796                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
21797                 continue;
21798             }
21799             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
21800                 app.pssProcState = app.setProcState;
21801                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
21802                         mTestPssMode, isSleepingLocked(), now);
21803                 mPendingPssProcesses.add(app);
21804             }
21805         }
21806         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
21807     }
21808
21809     public void setTestPssMode(boolean enabled) {
21810         synchronized (this) {
21811             mTestPssMode = enabled;
21812             if (enabled) {
21813                 // Whenever we enable the mode, we want to take a snapshot all of current
21814                 // process mem use.
21815                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
21816             }
21817         }
21818     }
21819
21820     /**
21821      * Ask a given process to GC right now.
21822      */
21823     final void performAppGcLocked(ProcessRecord app) {
21824         try {
21825             app.lastRequestedGc = SystemClock.uptimeMillis();
21826             if (app.thread != null) {
21827                 if (app.reportLowMemory) {
21828                     app.reportLowMemory = false;
21829                     app.thread.scheduleLowMemory();
21830                 } else {
21831                     app.thread.processInBackground();
21832                 }
21833             }
21834         } catch (Exception e) {
21835             // whatever.
21836         }
21837     }
21838
21839     /**
21840      * Returns true if things are idle enough to perform GCs.
21841      */
21842     private final boolean canGcNowLocked() {
21843         boolean processingBroadcasts = false;
21844         for (BroadcastQueue q : mBroadcastQueues) {
21845             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
21846                 processingBroadcasts = true;
21847             }
21848         }
21849         return !processingBroadcasts
21850                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
21851     }
21852
21853     /**
21854      * Perform GCs on all processes that are waiting for it, but only
21855      * if things are idle.
21856      */
21857     final void performAppGcsLocked() {
21858         final int N = mProcessesToGc.size();
21859         if (N <= 0) {
21860             return;
21861         }
21862         if (canGcNowLocked()) {
21863             while (mProcessesToGc.size() > 0) {
21864                 ProcessRecord proc = mProcessesToGc.remove(0);
21865                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
21866                     if ((proc.lastRequestedGc+mConstants.GC_MIN_INTERVAL)
21867                             <= SystemClock.uptimeMillis()) {
21868                         // To avoid spamming the system, we will GC processes one
21869                         // at a time, waiting a few seconds between each.
21870                         performAppGcLocked(proc);
21871                         scheduleAppGcsLocked();
21872                         return;
21873                     } else {
21874                         // It hasn't been long enough since we last GCed this
21875                         // process...  put it in the list to wait for its time.
21876                         addProcessToGcListLocked(proc);
21877                         break;
21878                     }
21879                 }
21880             }
21881
21882             scheduleAppGcsLocked();
21883         }
21884     }
21885
21886     /**
21887      * If all looks good, perform GCs on all processes waiting for them.
21888      */
21889     final void performAppGcsIfAppropriateLocked() {
21890         if (canGcNowLocked()) {
21891             performAppGcsLocked();
21892             return;
21893         }
21894         // Still not idle, wait some more.
21895         scheduleAppGcsLocked();
21896     }
21897
21898     /**
21899      * Schedule the execution of all pending app GCs.
21900      */
21901     final void scheduleAppGcsLocked() {
21902         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
21903
21904         if (mProcessesToGc.size() > 0) {
21905             // Schedule a GC for the time to the next process.
21906             ProcessRecord proc = mProcessesToGc.get(0);
21907             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
21908
21909             long when = proc.lastRequestedGc + mConstants.GC_MIN_INTERVAL;
21910             long now = SystemClock.uptimeMillis();
21911             if (when < (now+mConstants.GC_TIMEOUT)) {
21912                 when = now + mConstants.GC_TIMEOUT;
21913             }
21914             mHandler.sendMessageAtTime(msg, when);
21915         }
21916     }
21917
21918     /**
21919      * Add a process to the array of processes waiting to be GCed.  Keeps the
21920      * list in sorted order by the last GC time.  The process can't already be
21921      * on the list.
21922      */
21923     final void addProcessToGcListLocked(ProcessRecord proc) {
21924         boolean added = false;
21925         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
21926             if (mProcessesToGc.get(i).lastRequestedGc <
21927                     proc.lastRequestedGc) {
21928                 added = true;
21929                 mProcessesToGc.add(i+1, proc);
21930                 break;
21931             }
21932         }
21933         if (!added) {
21934             mProcessesToGc.add(0, proc);
21935         }
21936     }
21937
21938     /**
21939      * Set up to ask a process to GC itself.  This will either do it
21940      * immediately, or put it on the list of processes to gc the next
21941      * time things are idle.
21942      */
21943     final void scheduleAppGcLocked(ProcessRecord app) {
21944         long now = SystemClock.uptimeMillis();
21945         if ((app.lastRequestedGc+mConstants.GC_MIN_INTERVAL) > now) {
21946             return;
21947         }
21948         if (!mProcessesToGc.contains(app)) {
21949             addProcessToGcListLocked(app);
21950             scheduleAppGcsLocked();
21951         }
21952     }
21953
21954     final void checkExcessivePowerUsageLocked() {
21955         updateCpuStatsNow();
21956
21957         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
21958         boolean doCpuKills = true;
21959         if (mLastPowerCheckUptime == 0) {
21960             doCpuKills = false;
21961         }
21962         final long curUptime = SystemClock.uptimeMillis();
21963         final long uptimeSince = curUptime - mLastPowerCheckUptime;
21964         mLastPowerCheckUptime = curUptime;
21965         int i = mLruProcesses.size();
21966         while (i > 0) {
21967             i--;
21968             ProcessRecord app = mLruProcesses.get(i);
21969             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
21970                 if (app.lastCpuTime <= 0) {
21971                     continue;
21972                 }
21973                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
21974                 if (DEBUG_POWER) {
21975                     StringBuilder sb = new StringBuilder(128);
21976                     sb.append("CPU for ");
21977                     app.toShortString(sb);
21978                     sb.append(": over ");
21979                     TimeUtils.formatDuration(uptimeSince, sb);
21980                     sb.append(" used ");
21981                     TimeUtils.formatDuration(cputimeUsed, sb);
21982                     sb.append(" (");
21983                     sb.append((cputimeUsed*100)/uptimeSince);
21984                     sb.append("%)");
21985                     Slog.i(TAG_POWER, sb.toString());
21986                 }
21987                 // If the process has used too much CPU over the last duration, the
21988                 // user probably doesn't want this, so kill!
21989                 if (doCpuKills && uptimeSince > 0) {
21990                     // What is the limit for this process?
21991                     int cpuLimit;
21992                     long checkDur = curUptime - app.whenUnimportant;
21993                     if (checkDur <= mConstants.POWER_CHECK_INTERVAL) {
21994                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_1;
21995                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*2)
21996                             || app.setProcState <= ActivityManager.PROCESS_STATE_HOME) {
21997                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_2;
21998                     } else if (checkDur <= (mConstants.POWER_CHECK_INTERVAL*3)) {
21999                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_3;
22000                     } else {
22001                         cpuLimit = mConstants.POWER_CHECK_MAX_CPU_4;
22002                     }
22003                     if (((cputimeUsed*100)/uptimeSince) >= cpuLimit) {
22004                         synchronized (stats) {
22005                             stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
22006                                     uptimeSince, cputimeUsed);
22007                         }
22008                         app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince
22009                                 + " dur=" + checkDur + " limit=" + cpuLimit, true);
22010                         app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
22011                     }
22012                 }
22013                 app.lastCpuTime = app.curCpuTime;
22014             }
22015         }
22016     }
22017
22018     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
22019             long nowElapsed) {
22020         boolean success = true;
22021
22022         if (app.curRawAdj != app.setRawAdj) {
22023             app.setRawAdj = app.curRawAdj;
22024         }
22025
22026         int changes = 0;
22027
22028         if (app.curAdj != app.setAdj) {
22029             ProcessList.setOomAdj(app.pid, app.uid, app.curAdj);
22030             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.info.uid) {
22031                 String msg = "Set " + app.pid + " " + app.processName + " adj "
22032                         + app.curAdj + ": " + app.adjType;
22033                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22034             }
22035             app.setAdj = app.curAdj;
22036             app.verifiedAdj = ProcessList.INVALID_ADJ;
22037         }
22038
22039         if (app.setSchedGroup != app.curSchedGroup) {
22040             int oldSchedGroup = app.setSchedGroup;
22041             app.setSchedGroup = app.curSchedGroup;
22042             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22043                 String msg = "Setting sched group of " + app.processName
22044                         + " to " + app.curSchedGroup;
22045                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22046             }
22047             if (app.waitingToKill != null && app.curReceivers.isEmpty()
22048                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
22049                 app.kill(app.waitingToKill, true);
22050                 success = false;
22051             } else {
22052                 int processGroup;
22053                 switch (app.curSchedGroup) {
22054                     case ProcessList.SCHED_GROUP_BACKGROUND:
22055                         processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
22056                         break;
22057                     case ProcessList.SCHED_GROUP_TOP_APP:
22058                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
22059                         processGroup = THREAD_GROUP_TOP_APP;
22060                         break;
22061                     default:
22062                         processGroup = THREAD_GROUP_DEFAULT;
22063                         break;
22064                 }
22065                 long oldId = Binder.clearCallingIdentity();
22066                 try {
22067                     setProcessGroup(app.pid, processGroup);
22068                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
22069                         // do nothing if we already switched to RT
22070                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22071                             mVrController.onTopProcChangedLocked(app);
22072                             if (mUseFifoUiScheduling) {
22073                                 // Switch UI pipeline for app to SCHED_FIFO
22074                                 app.savedPriority = Process.getThreadPriority(app.pid);
22075                                 scheduleAsFifoPriority(app.pid, /* suppressLogs */true);
22076                                 if (app.renderThreadTid != 0) {
22077                                     scheduleAsFifoPriority(app.renderThreadTid,
22078                                         /* suppressLogs */true);
22079                                     if (DEBUG_OOM_ADJ) {
22080                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
22081                                             app.renderThreadTid + ") to FIFO");
22082                                     }
22083                                 } else {
22084                                     if (DEBUG_OOM_ADJ) {
22085                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
22086                                     }
22087                                 }
22088                             } else {
22089                                 // Boost priority for top app UI and render threads
22090                                 setThreadPriority(app.pid, TOP_APP_PRIORITY_BOOST);
22091                                 if (app.renderThreadTid != 0) {
22092                                     try {
22093                                         setThreadPriority(app.renderThreadTid,
22094                                                 TOP_APP_PRIORITY_BOOST);
22095                                     } catch (IllegalArgumentException e) {
22096                                         // thread died, ignore
22097                                     }
22098                                 }
22099                             }
22100                         }
22101                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
22102                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
22103                         mVrController.onTopProcChangedLocked(app);
22104                         if (mUseFifoUiScheduling) {
22105                             try {
22106                                 // Reset UI pipeline to SCHED_OTHER
22107                                 setThreadScheduler(app.pid, SCHED_OTHER, 0);
22108                                 setThreadPriority(app.pid, app.savedPriority);
22109                                 if (app.renderThreadTid != 0) {
22110                                     setThreadScheduler(app.renderThreadTid,
22111                                         SCHED_OTHER, 0);
22112                                     setThreadPriority(app.renderThreadTid, -4);
22113                                 }
22114                             } catch (IllegalArgumentException e) {
22115                                 Slog.w(TAG,
22116                                         "Failed to set scheduling policy, thread does not exist:\n"
22117                                                 + e);
22118                             } catch (SecurityException e) {
22119                                 Slog.w(TAG, "Failed to set scheduling policy, not allowed:\n" + e);
22120                             }
22121                         } else {
22122                             // Reset priority for top app UI and render threads
22123                             setThreadPriority(app.pid, 0);
22124                             if (app.renderThreadTid != 0) {
22125                                 setThreadPriority(app.renderThreadTid, 0);
22126                             }
22127                         }
22128                     }
22129                 } catch (Exception e) {
22130                     if (false) {
22131                         Slog.w(TAG, "Failed setting process group of " + app.pid
22132                                 + " to " + app.curSchedGroup);
22133                         Slog.w(TAG, "at location", e);
22134                     }
22135                 } finally {
22136                     Binder.restoreCallingIdentity(oldId);
22137                 }
22138             }
22139         }
22140         if (app.repForegroundActivities != app.foregroundActivities) {
22141             app.repForegroundActivities = app.foregroundActivities;
22142             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
22143         }
22144         if (app.repProcState != app.curProcState) {
22145             app.repProcState = app.curProcState;
22146             if (app.thread != null) {
22147                 try {
22148                     if (false) {
22149                         //RuntimeException h = new RuntimeException("here");
22150                         Slog.i(TAG, "Sending new process state " + app.repProcState
22151                                 + " to " + app /*, h*/);
22152                     }
22153                     app.thread.setProcessState(app.repProcState);
22154                 } catch (RemoteException e) {
22155                 }
22156             }
22157         }
22158         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
22159                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
22160             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
22161                 // Experimental code to more aggressively collect pss while
22162                 // running test...  the problem is that this tends to collect
22163                 // the data right when a process is transitioning between process
22164                 // states, which well tend to give noisy data.
22165                 long start = SystemClock.uptimeMillis();
22166                 long pss = Debug.getPss(app.pid, mTmpLong, null);
22167                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
22168                 mPendingPssProcesses.remove(app);
22169                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
22170                         + " to " + app.curProcState + ": "
22171                         + (SystemClock.uptimeMillis()-start) + "ms");
22172             }
22173             app.lastStateTime = now;
22174             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
22175                     mTestPssMode, isSleepingLocked(), now);
22176             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
22177                     + ProcessList.makeProcStateString(app.setProcState) + " to "
22178                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
22179                     + (app.nextPssTime-now) + ": " + app);
22180         } else {
22181             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
22182                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
22183                     mTestPssMode)))) {
22184                 requestPssLocked(app, app.setProcState);
22185                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
22186                         mTestPssMode, isSleepingLocked(), now);
22187             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
22188                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
22189         }
22190         if (app.setProcState != app.curProcState) {
22191             if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mCurOomAdjUid == app.uid) {
22192                 String msg = "Proc state change of " + app.processName
22193                         + " to " + app.curProcState;
22194                 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg);
22195             }
22196             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
22197             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
22198             if (setImportant && !curImportant) {
22199                 // This app is no longer something we consider important enough to allow to
22200                 // use arbitrary amounts of battery power.  Note
22201                 // its current CPU time to later know to kill it if
22202                 // it is not behaving well.
22203                 app.whenUnimportant = now;
22204                 app.lastCpuTime = 0;
22205             }
22206             // Inform UsageStats of important process state change
22207             // Must be called before updating setProcState
22208             maybeUpdateUsageStatsLocked(app, nowElapsed);
22209
22210             app.setProcState = app.curProcState;
22211             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
22212                 app.notCachedSinceIdle = false;
22213             }
22214             if (!doingAll) {
22215                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
22216             } else {
22217                 app.procStateChanged = true;
22218             }
22219         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
22220                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL) {
22221             // For apps that sit around for a long time in the interactive state, we need
22222             // to report this at least once a day so they don't go idle.
22223             maybeUpdateUsageStatsLocked(app, nowElapsed);
22224         }
22225
22226         if (changes != 0) {
22227             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22228                     "Changes in " + app + ": " + changes);
22229             int i = mPendingProcessChanges.size()-1;
22230             ProcessChangeItem item = null;
22231             while (i >= 0) {
22232                 item = mPendingProcessChanges.get(i);
22233                 if (item.pid == app.pid) {
22234                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22235                             "Re-using existing item: " + item);
22236                     break;
22237                 }
22238                 i--;
22239             }
22240             if (i < 0) {
22241                 // No existing item in pending changes; need a new one.
22242                 final int NA = mAvailProcessChanges.size();
22243                 if (NA > 0) {
22244                     item = mAvailProcessChanges.remove(NA-1);
22245                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22246                             "Retrieving available item: " + item);
22247                 } else {
22248                     item = new ProcessChangeItem();
22249                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22250                             "Allocating new item: " + item);
22251                 }
22252                 item.changes = 0;
22253                 item.pid = app.pid;
22254                 item.uid = app.info.uid;
22255                 if (mPendingProcessChanges.size() == 0) {
22256                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22257                             "*** Enqueueing dispatch processes changed!");
22258                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
22259                 }
22260                 mPendingProcessChanges.add(item);
22261             }
22262             item.changes |= changes;
22263             item.foregroundActivities = app.repForegroundActivities;
22264             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
22265                     "Item " + Integer.toHexString(System.identityHashCode(item))
22266                     + " " + app.toShortString() + ": changes=" + item.changes
22267                     + " foreground=" + item.foregroundActivities
22268                     + " type=" + app.adjType + " source=" + app.adjSource
22269                     + " target=" + app.adjTarget);
22270         }
22271
22272         return success;
22273     }
22274
22275     private boolean isEphemeralLocked(int uid) {
22276         String packages[] = mContext.getPackageManager().getPackagesForUid(uid);
22277         if (packages == null || packages.length != 1) { // Ephemeral apps cannot share uid
22278             return false;
22279         }
22280         return getPackageManagerInternalLocked().isPackageEphemeral(UserHandle.getUserId(uid),
22281                 packages[0]);
22282     }
22283
22284     @VisibleForTesting
22285     final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
22286         final UidRecord.ChangeItem pendingChange;
22287         if (uidRec == null || uidRec.pendingChange == null) {
22288             if (mPendingUidChanges.size() == 0) {
22289                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22290                         "*** Enqueueing dispatch uid changed!");
22291                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
22292             }
22293             final int NA = mAvailUidChanges.size();
22294             if (NA > 0) {
22295                 pendingChange = mAvailUidChanges.remove(NA-1);
22296                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22297                         "Retrieving available item: " + pendingChange);
22298             } else {
22299                 pendingChange = new UidRecord.ChangeItem();
22300                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22301                         "Allocating new item: " + pendingChange);
22302             }
22303             if (uidRec != null) {
22304                 uidRec.pendingChange = pendingChange;
22305                 if ((change & UidRecord.CHANGE_GONE) != 0 && !uidRec.idle) {
22306                     // If this uid is going away, and we haven't yet reported it is gone,
22307                     // then do so now.
22308                     change |= UidRecord.CHANGE_IDLE;
22309                 }
22310             } else if (uid < 0) {
22311                 throw new IllegalArgumentException("No UidRecord or uid");
22312             }
22313             pendingChange.uidRecord = uidRec;
22314             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
22315             mPendingUidChanges.add(pendingChange);
22316         } else {
22317             pendingChange = uidRec.pendingChange;
22318             // If there is no change in idle or active state, then keep whatever was pending.
22319             if ((change & (UidRecord.CHANGE_IDLE | UidRecord.CHANGE_ACTIVE)) == 0) {
22320                 change |= (pendingChange.change & (UidRecord.CHANGE_IDLE
22321                         | UidRecord.CHANGE_ACTIVE));
22322             }
22323             // If there is no change in cached or uncached state, then keep whatever was pending.
22324             if ((change & (UidRecord.CHANGE_CACHED | UidRecord.CHANGE_UNCACHED)) == 0) {
22325                 change |= (pendingChange.change & (UidRecord.CHANGE_CACHED
22326                         | UidRecord.CHANGE_UNCACHED));
22327             }
22328             // If this is a report of the UID being gone, then we shouldn't keep any previous
22329             // report of it being active or cached.  (That is, a gone uid is never active,
22330             // and never cached.)
22331             if ((change & UidRecord.CHANGE_GONE) != 0) {
22332                 change &= ~(UidRecord.CHANGE_ACTIVE | UidRecord.CHANGE_CACHED);
22333                 if (!uidRec.idle) {
22334                     // If this uid is going away, and we haven't yet reported it is gone,
22335                     // then do so now.
22336                     change |= UidRecord.CHANGE_IDLE;
22337                 }
22338             }
22339         }
22340         pendingChange.change = change;
22341         pendingChange.processState = uidRec != null
22342                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
22343         pendingChange.ephemeral = uidRec != null ? uidRec.ephemeral : isEphemeralLocked(uid);
22344         pendingChange.procStateSeq = uidRec != null ? uidRec.curProcStateSeq : 0;
22345         if (uidRec != null) {
22346             uidRec.lastReportedChange = change;
22347             uidRec.updateLastDispatchedProcStateSeq(change);
22348         }
22349
22350         // Directly update the power manager, since we sit on top of it and it is critical
22351         // it be kept in sync (so wake locks will be held as soon as appropriate).
22352         if (mLocalPowerManager != null) {
22353             // TO DO: dispatch cached/uncached changes here, so we don't need to report
22354             // all proc state changes.
22355             if ((change & UidRecord.CHANGE_ACTIVE) != 0) {
22356                 mLocalPowerManager.uidActive(pendingChange.uid);
22357             }
22358             if ((change & UidRecord.CHANGE_IDLE) != 0) {
22359                 mLocalPowerManager.uidIdle(pendingChange.uid);
22360             }
22361             if ((change & UidRecord.CHANGE_GONE) != 0) {
22362                 mLocalPowerManager.uidGone(pendingChange.uid);
22363             } else {
22364                 mLocalPowerManager.updateUidProcState(pendingChange.uid,
22365                         pendingChange.processState);
22366             }
22367         }
22368     }
22369
22370     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
22371             String authority) {
22372         if (app == null) return;
22373         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
22374             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
22375             if (userState == null) return;
22376             final long now = SystemClock.elapsedRealtime();
22377             Long lastReported = userState.mProviderLastReportedFg.get(authority);
22378             if (lastReported == null || lastReported < now - 60 * 1000L) {
22379                 if (mSystemReady) {
22380                     // Cannot touch the user stats if not system ready
22381                     mUsageStatsService.reportContentProviderUsage(
22382                             authority, providerPkgName, app.userId);
22383                 }
22384                 userState.mProviderLastReportedFg.put(authority, now);
22385             }
22386         }
22387     }
22388
22389     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
22390         if (DEBUG_USAGE_STATS) {
22391             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
22392                     + "] state changes: old = " + app.setProcState + ", new = "
22393                     + app.curProcState);
22394         }
22395         if (mUsageStatsService == null) {
22396             return;
22397         }
22398         boolean isInteraction;
22399         // To avoid some abuse patterns, we are going to be careful about what we consider
22400         // to be an app interaction.  Being the top activity doesn't count while the display
22401         // is sleeping, nor do short foreground services.
22402         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
22403             isInteraction = true;
22404             app.fgInteractionTime = 0;
22405         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
22406             if (app.fgInteractionTime == 0) {
22407                 app.fgInteractionTime = nowElapsed;
22408                 isInteraction = false;
22409             } else {
22410                 isInteraction = nowElapsed > app.fgInteractionTime
22411                         + mConstants.SERVICE_USAGE_INTERACTION_TIME;
22412             }
22413         } else {
22414             isInteraction = app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
22415             app.fgInteractionTime = 0;
22416         }
22417         if (isInteraction && (!app.reportedInteraction || (nowElapsed-app.interactionEventTime)
22418                 > mConstants.USAGE_STATS_INTERACTION_INTERVAL)) {
22419             app.interactionEventTime = nowElapsed;
22420             String[] packages = app.getPackageList();
22421             if (packages != null) {
22422                 for (int i = 0; i < packages.length; i++) {
22423                     mUsageStatsService.reportEvent(packages[i], app.userId,
22424                             UsageEvents.Event.SYSTEM_INTERACTION);
22425                 }
22426             }
22427         }
22428         app.reportedInteraction = isInteraction;
22429         if (!isInteraction) {
22430             app.interactionEventTime = 0;
22431         }
22432     }
22433
22434     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
22435         if (proc.thread != null) {
22436             if (proc.baseProcessTracker != null) {
22437                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
22438             }
22439         }
22440     }
22441
22442     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
22443             ProcessRecord TOP_APP, boolean doingAll, long now) {
22444         if (app.thread == null) {
22445             return false;
22446         }
22447
22448         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
22449
22450         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
22451     }
22452
22453     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
22454             boolean oomAdj) {
22455         if (isForeground != proc.foregroundServices) {
22456             proc.foregroundServices = isForeground;
22457             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
22458                     proc.info.uid);
22459             if (isForeground) {
22460                 if (curProcs == null) {
22461                     curProcs = new ArrayList<ProcessRecord>();
22462                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
22463                 }
22464                 if (!curProcs.contains(proc)) {
22465                     curProcs.add(proc);
22466                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
22467                             proc.info.packageName, proc.info.uid);
22468                 }
22469             } else {
22470                 if (curProcs != null) {
22471                     if (curProcs.remove(proc)) {
22472                         mBatteryStatsService.noteEvent(
22473                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
22474                                 proc.info.packageName, proc.info.uid);
22475                         if (curProcs.size() <= 0) {
22476                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
22477                         }
22478                     }
22479                 }
22480             }
22481             if (oomAdj) {
22482                 updateOomAdjLocked();
22483             }
22484         }
22485     }
22486
22487     private final ActivityRecord resumedAppLocked() {
22488         ActivityRecord act = mStackSupervisor.getResumedActivityLocked();
22489         String pkg;
22490         int uid;
22491         if (act != null) {
22492             pkg = act.packageName;
22493             uid = act.info.applicationInfo.uid;
22494         } else {
22495             pkg = null;
22496             uid = -1;
22497         }
22498         // Has the UID or resumed package name changed?
22499         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
22500                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
22501             if (mCurResumedPackage != null) {
22502                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
22503                         mCurResumedPackage, mCurResumedUid);
22504             }
22505             mCurResumedPackage = pkg;
22506             mCurResumedUid = uid;
22507             if (mCurResumedPackage != null) {
22508                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
22509                         mCurResumedPackage, mCurResumedUid);
22510             }
22511         }
22512         return act;
22513     }
22514
22515     /**
22516      * Update OomAdj for a specific process.
22517      * @param app The process to update
22518      * @param oomAdjAll If it's ok to call updateOomAdjLocked() for all running apps
22519      *                  if necessary, or skip.
22520      * @return whether updateOomAdjLocked(app) was successful.
22521      */
22522     final boolean updateOomAdjLocked(ProcessRecord app, boolean oomAdjAll) {
22523         final ActivityRecord TOP_ACT = resumedAppLocked();
22524         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22525         final boolean wasCached = app.cached;
22526
22527         mAdjSeq++;
22528
22529         // This is the desired cached adjusment we want to tell it to use.
22530         // If our app is currently cached, we know it, and that is it.  Otherwise,
22531         // we don't know it yet, and it needs to now be cached we will then
22532         // need to do a complete oom adj.
22533         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
22534                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
22535         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
22536                 SystemClock.uptimeMillis());
22537         if (oomAdjAll
22538                 && (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ)) {
22539             // Changed to/from cached state, so apps after it in the LRU
22540             // list may also be changed.
22541             updateOomAdjLocked();
22542         }
22543         return success;
22544     }
22545
22546     final void updateOomAdjLocked() {
22547         final ActivityRecord TOP_ACT = resumedAppLocked();
22548         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
22549         final long now = SystemClock.uptimeMillis();
22550         final long nowElapsed = SystemClock.elapsedRealtime();
22551         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
22552         final int N = mLruProcesses.size();
22553
22554         if (false) {
22555             RuntimeException e = new RuntimeException();
22556             e.fillInStackTrace();
22557             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
22558         }
22559
22560         // Reset state in all uid records.
22561         for (int i=mActiveUids.size()-1; i>=0; i--) {
22562             final UidRecord uidRec = mActiveUids.valueAt(i);
22563             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22564                     "Starting update of " + uidRec);
22565             uidRec.reset();
22566         }
22567
22568         mStackSupervisor.rankTaskLayersIfNeeded();
22569
22570         mAdjSeq++;
22571         mNewNumServiceProcs = 0;
22572         mNewNumAServiceProcs = 0;
22573
22574         final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES;
22575         final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit;
22576
22577         // Let's determine how many processes we have running vs.
22578         // how many slots we have for background processes; we may want
22579         // to put multiple processes in a slot of there are enough of
22580         // them.
22581         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
22582                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
22583         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
22584         if (numEmptyProcs > cachedProcessLimit) {
22585             // If there are more empty processes than our limit on cached
22586             // processes, then use the cached process limit for the factor.
22587             // This ensures that the really old empty processes get pushed
22588             // down to the bottom, so if we are running low on memory we will
22589             // have a better chance at keeping around more cached processes
22590             // instead of a gazillion empty processes.
22591             numEmptyProcs = cachedProcessLimit;
22592         }
22593         int emptyFactor = numEmptyProcs/numSlots;
22594         if (emptyFactor < 1) emptyFactor = 1;
22595         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
22596         if (cachedFactor < 1) cachedFactor = 1;
22597         int stepCached = 0;
22598         int stepEmpty = 0;
22599         int numCached = 0;
22600         int numEmpty = 0;
22601         int numTrimming = 0;
22602
22603         mNumNonCachedProcs = 0;
22604         mNumCachedHiddenProcs = 0;
22605
22606         // First update the OOM adjustment for each of the
22607         // application processes based on their current state.
22608         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
22609         int nextCachedAdj = curCachedAdj+1;
22610         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
22611         int nextEmptyAdj = curEmptyAdj+2;
22612         for (int i=N-1; i>=0; i--) {
22613             ProcessRecord app = mLruProcesses.get(i);
22614             if (!app.killedByAm && app.thread != null) {
22615                 app.procStateChanged = false;
22616                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
22617
22618                 // If we haven't yet assigned the final cached adj
22619                 // to the process, do that now.
22620                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
22621                     switch (app.curProcState) {
22622                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22623                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22624                             // This process is a cached process holding activities...
22625                             // assign it the next cached value for that type, and then
22626                             // step that cached level.
22627                             app.curRawAdj = curCachedAdj;
22628                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
22629                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
22630                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
22631                                     + ")");
22632                             if (curCachedAdj != nextCachedAdj) {
22633                                 stepCached++;
22634                                 if (stepCached >= cachedFactor) {
22635                                     stepCached = 0;
22636                                     curCachedAdj = nextCachedAdj;
22637                                     nextCachedAdj += 2;
22638                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22639                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
22640                                     }
22641                                 }
22642                             }
22643                             break;
22644                         default:
22645                             // For everything else, assign next empty cached process
22646                             // level and bump that up.  Note that this means that
22647                             // long-running services that have dropped down to the
22648                             // cached level will be treated as empty (since their process
22649                             // state is still as a service), which is what we want.
22650                             app.curRawAdj = curEmptyAdj;
22651                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
22652                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
22653                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
22654                                     + ")");
22655                             if (curEmptyAdj != nextEmptyAdj) {
22656                                 stepEmpty++;
22657                                 if (stepEmpty >= emptyFactor) {
22658                                     stepEmpty = 0;
22659                                     curEmptyAdj = nextEmptyAdj;
22660                                     nextEmptyAdj += 2;
22661                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
22662                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
22663                                     }
22664                                 }
22665                             }
22666                             break;
22667                     }
22668                 }
22669
22670                 applyOomAdjLocked(app, true, now, nowElapsed);
22671
22672                 // Count the number of process types.
22673                 switch (app.curProcState) {
22674                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
22675                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
22676                         mNumCachedHiddenProcs++;
22677                         numCached++;
22678                         if (numCached > cachedProcessLimit) {
22679                             app.kill("cached #" + numCached, true);
22680                         }
22681                         break;
22682                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
22683                         if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES
22684                                 && app.lastActivityTime < oldTime) {
22685                             app.kill("empty for "
22686                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
22687                                     / 1000) + "s", true);
22688                         } else {
22689                             numEmpty++;
22690                             if (numEmpty > emptyProcessLimit) {
22691                                 app.kill("empty #" + numEmpty, true);
22692                             }
22693                         }
22694                         break;
22695                     default:
22696                         mNumNonCachedProcs++;
22697                         break;
22698                 }
22699
22700                 if (app.isolated && app.services.size() <= 0) {
22701                     // If this is an isolated process, and there are no
22702                     // services running in it, then the process is no longer
22703                     // needed.  We agressively kill these because we can by
22704                     // definition not re-use the same process again, and it is
22705                     // good to avoid having whatever code was running in them
22706                     // left sitting around after no longer needed.
22707                     app.kill("isolated not needed", true);
22708                 } else {
22709                     // Keeping this process, update its uid.
22710                     final UidRecord uidRec = app.uidRecord;
22711                     if (uidRec != null) {
22712                         uidRec.ephemeral = app.info.isInstantApp();
22713                         if (uidRec.curProcState > app.curProcState) {
22714                             uidRec.curProcState = app.curProcState;
22715                         }
22716                         if (app.foregroundServices) {
22717                             uidRec.foregroundServices = true;
22718                         }
22719                     }
22720                 }
22721
22722                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22723                         && !app.killedByAm) {
22724                     numTrimming++;
22725                 }
22726             }
22727         }
22728
22729         incrementProcStateSeqAndNotifyAppsLocked();
22730
22731         mNumServiceProcs = mNewNumServiceProcs;
22732
22733         // Now determine the memory trimming level of background processes.
22734         // Unfortunately we need to start at the back of the list to do this
22735         // properly.  We only do this if the number of background apps we
22736         // are managing to keep around is less than half the maximum we desire;
22737         // if we are keeping a good number around, we'll let them use whatever
22738         // memory they want.
22739         final int numCachedAndEmpty = numCached + numEmpty;
22740         int memFactor;
22741         if (numCached <= mConstants.CUR_TRIM_CACHED_PROCESSES
22742                 && numEmpty <= mConstants.CUR_TRIM_EMPTY_PROCESSES) {
22743             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
22744                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
22745             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
22746                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
22747             } else {
22748                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
22749             }
22750         } else {
22751             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
22752         }
22753         // We always allow the memory level to go up (better).  We only allow it to go
22754         // down if we are in a state where that is allowed, *and* the total number of processes
22755         // has gone down since last time.
22756         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
22757                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
22758                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
22759         if (memFactor > mLastMemoryLevel) {
22760             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
22761                 memFactor = mLastMemoryLevel;
22762                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
22763             }
22764         }
22765         if (memFactor != mLastMemoryLevel) {
22766             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
22767         }
22768         mLastMemoryLevel = memFactor;
22769         mLastNumProcesses = mLruProcesses.size();
22770         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
22771         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
22772         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
22773             if (mLowRamStartTime == 0) {
22774                 mLowRamStartTime = now;
22775             }
22776             int step = 0;
22777             int fgTrimLevel;
22778             switch (memFactor) {
22779                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
22780                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
22781                     break;
22782                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
22783                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
22784                     break;
22785                 default:
22786                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
22787                     break;
22788             }
22789             int factor = numTrimming/3;
22790             int minFactor = 2;
22791             if (mHomeProcess != null) minFactor++;
22792             if (mPreviousProcess != null) minFactor++;
22793             if (factor < minFactor) factor = minFactor;
22794             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
22795             for (int i=N-1; i>=0; i--) {
22796                 ProcessRecord app = mLruProcesses.get(i);
22797                 if (allChanged || app.procStateChanged) {
22798                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22799                     app.procStateChanged = false;
22800                 }
22801                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
22802                         && !app.killedByAm) {
22803                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
22804                         try {
22805                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22806                                     "Trimming memory of " + app.processName + " to " + curLevel);
22807                             app.thread.scheduleTrimMemory(curLevel);
22808                         } catch (RemoteException e) {
22809                         }
22810                         if (false) {
22811                             // For now we won't do this; our memory trimming seems
22812                             // to be good enough at this point that destroying
22813                             // activities causes more harm than good.
22814                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
22815                                     && app != mHomeProcess && app != mPreviousProcess) {
22816                                 // Need to do this on its own message because the stack may not
22817                                 // be in a consistent state at this point.
22818                                 // For these apps we will also finish their activities
22819                                 // to help them free memory.
22820                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
22821                             }
22822                         }
22823                     }
22824                     app.trimMemoryLevel = curLevel;
22825                     step++;
22826                     if (step >= factor) {
22827                         step = 0;
22828                         switch (curLevel) {
22829                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
22830                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
22831                                 break;
22832                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
22833                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22834                                 break;
22835                         }
22836                     }
22837                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
22838                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
22839                             && app.thread != null) {
22840                         try {
22841                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22842                                     "Trimming memory of heavy-weight " + app.processName
22843                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22844                             app.thread.scheduleTrimMemory(
22845                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
22846                         } catch (RemoteException e) {
22847                         }
22848                     }
22849                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
22850                 } else {
22851                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22852                             || app.systemNoUi) && app.pendingUiClean) {
22853                         // If this application is now in the background and it
22854                         // had done UI, then give it the special trim level to
22855                         // have it free UI resources.
22856                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
22857                         if (app.trimMemoryLevel < level && app.thread != null) {
22858                             try {
22859                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22860                                         "Trimming memory of bg-ui " + app.processName
22861                                         + " to " + level);
22862                                 app.thread.scheduleTrimMemory(level);
22863                             } catch (RemoteException e) {
22864                             }
22865                         }
22866                         app.pendingUiClean = false;
22867                     }
22868                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
22869                         try {
22870                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22871                                     "Trimming memory of fg " + app.processName
22872                                     + " to " + fgTrimLevel);
22873                             app.thread.scheduleTrimMemory(fgTrimLevel);
22874                         } catch (RemoteException e) {
22875                         }
22876                     }
22877                     app.trimMemoryLevel = fgTrimLevel;
22878                 }
22879             }
22880         } else {
22881             if (mLowRamStartTime != 0) {
22882                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
22883                 mLowRamStartTime = 0;
22884             }
22885             for (int i=N-1; i>=0; i--) {
22886                 ProcessRecord app = mLruProcesses.get(i);
22887                 if (allChanged || app.procStateChanged) {
22888                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
22889                     app.procStateChanged = false;
22890                 }
22891                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
22892                         || app.systemNoUi) && app.pendingUiClean) {
22893                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
22894                             && app.thread != null) {
22895                         try {
22896                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
22897                                     "Trimming memory of ui hidden " + app.processName
22898                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22899                             app.thread.scheduleTrimMemory(
22900                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
22901                         } catch (RemoteException e) {
22902                         }
22903                     }
22904                     app.pendingUiClean = false;
22905                 }
22906                 app.trimMemoryLevel = 0;
22907             }
22908         }
22909
22910         if (mAlwaysFinishActivities) {
22911             // Need to do this on its own message because the stack may not
22912             // be in a consistent state at this point.
22913             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
22914         }
22915
22916         if (allChanged) {
22917             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
22918         }
22919
22920         ArrayList<UidRecord> becameIdle = null;
22921
22922         // Update from any uid changes.
22923         if (mLocalPowerManager != null) {
22924             mLocalPowerManager.startUidChanges();
22925         }
22926         for (int i=mActiveUids.size()-1; i>=0; i--) {
22927             final UidRecord uidRec = mActiveUids.valueAt(i);
22928             int uidChange = UidRecord.CHANGE_PROCSTATE;
22929             if (uidRec.curProcState != ActivityManager.PROCESS_STATE_NONEXISTENT
22930                     && (uidRec.setProcState != uidRec.curProcState
22931                            || uidRec.setWhitelist != uidRec.curWhitelist)) {
22932                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
22933                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
22934                         + " to " + uidRec.curProcState + ", whitelist from " + uidRec.setWhitelist
22935                         + " to " + uidRec.curWhitelist);
22936                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)
22937                         && !uidRec.curWhitelist) {
22938                     // UID is now in the background (and not on the temp whitelist).  Was it
22939                     // previously in the foreground (or on the temp whitelist)?
22940                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)
22941                             || uidRec.setWhitelist) {
22942                         uidRec.lastBackgroundTime = nowElapsed;
22943                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
22944                             // Note: the background settle time is in elapsed realtime, while
22945                             // the handler time base is uptime.  All this means is that we may
22946                             // stop background uids later than we had intended, but that only
22947                             // happens because the device was sleeping so we are okay anyway.
22948                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
22949                                     mConstants.BACKGROUND_SETTLE_TIME);
22950                         }
22951                     }
22952                     if (uidRec.idle && !uidRec.setIdle) {
22953                         uidChange = UidRecord.CHANGE_IDLE;
22954                         if (becameIdle == null) {
22955                             becameIdle = new ArrayList<>();
22956                         }
22957                         becameIdle.add(uidRec);
22958                     }
22959                 } else {
22960                     if (uidRec.idle) {
22961                         uidChange = UidRecord.CHANGE_ACTIVE;
22962                         EventLogTags.writeAmUidActive(uidRec.uid);
22963                         uidRec.idle = false;
22964                     }
22965                     uidRec.lastBackgroundTime = 0;
22966                 }
22967                 final boolean wasCached = uidRec.setProcState
22968                         > ActivityManager.PROCESS_STATE_RECEIVER;
22969                 final boolean isCached = uidRec.curProcState
22970                         > ActivityManager.PROCESS_STATE_RECEIVER;
22971                 if (wasCached != isCached ||
22972                         uidRec.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
22973                     uidChange |= isCached ? UidRecord.CHANGE_CACHED : UidRecord.CHANGE_UNCACHED;
22974                 }
22975                 uidRec.setProcState = uidRec.curProcState;
22976                 uidRec.setWhitelist = uidRec.curWhitelist;
22977                 uidRec.setIdle = uidRec.idle;
22978                 enqueueUidChangeLocked(uidRec, -1, uidChange);
22979                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
22980                 if (uidRec.foregroundServices) {
22981                     mServices.foregroundServiceProcStateChangedLocked(uidRec);
22982                 }
22983             }
22984         }
22985         if (mLocalPowerManager != null) {
22986             mLocalPowerManager.finishUidChanges();
22987         }
22988
22989         if (becameIdle != null) {
22990             // If we have any new uids that became idle this time, we need to make sure
22991             // they aren't left with running services.
22992             for (int i = becameIdle.size() - 1; i >= 0; i--) {
22993                 mServices.stopInBackgroundLocked(becameIdle.get(i).uid);
22994             }
22995         }
22996
22997         if (mProcessStats.shouldWriteNowLocked(now)) {
22998             mHandler.post(new Runnable() {
22999                 @Override public void run() {
23000                     synchronized (ActivityManagerService.this) {
23001                         mProcessStats.writeStateAsyncLocked();
23002                     }
23003                 }
23004             });
23005         }
23006
23007         if (DEBUG_OOM_ADJ) {
23008             final long duration = SystemClock.uptimeMillis() - now;
23009             if (false) {
23010                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
23011                         new RuntimeException("here").fillInStackTrace());
23012             } else {
23013                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
23014             }
23015         }
23016     }
23017
23018     @Override
23019     public void makePackageIdle(String packageName, int userId) {
23020         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
23021                 != PackageManager.PERMISSION_GRANTED) {
23022             String msg = "Permission Denial: makePackageIdle() from pid="
23023                     + Binder.getCallingPid()
23024                     + ", uid=" + Binder.getCallingUid()
23025                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
23026             Slog.w(TAG, msg);
23027             throw new SecurityException(msg);
23028         }
23029         final int callingPid = Binder.getCallingPid();
23030         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
23031                 userId, true, ALLOW_FULL_ONLY, "makePackageIdle", null);
23032         long callingId = Binder.clearCallingIdentity();
23033         synchronized(this) {
23034             try {
23035                 IPackageManager pm = AppGlobals.getPackageManager();
23036                 int pkgUid = -1;
23037                 try {
23038                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES
23039                             | MATCH_DEBUG_TRIAGED_MISSING, UserHandle.USER_SYSTEM);
23040                 } catch (RemoteException e) {
23041                 }
23042                 if (pkgUid == -1) {
23043                     throw new IllegalArgumentException("Unknown package name " + packageName);
23044                 }
23045
23046                 if (mLocalPowerManager != null) {
23047                     mLocalPowerManager.startUidChanges();
23048                 }
23049                 final int appId = UserHandle.getAppId(pkgUid);
23050                 final int N = mActiveUids.size();
23051                 for (int i=N-1; i>=0; i--) {
23052                     final UidRecord uidRec = mActiveUids.valueAt(i);
23053                     final long bgTime = uidRec.lastBackgroundTime;
23054                     if (bgTime > 0 && !uidRec.idle) {
23055                         if (UserHandle.getAppId(uidRec.uid) == appId) {
23056                             if (userId == UserHandle.USER_ALL ||
23057                                     userId == UserHandle.getUserId(uidRec.uid)) {
23058                                 EventLogTags.writeAmUidIdle(uidRec.uid);
23059                                 uidRec.idle = true;
23060                                 uidRec.setIdle = true;
23061                                 Slog.w(TAG, "Idling uid " + UserHandle.formatUid(uidRec.uid)
23062                                         + " from package " + packageName + " user " + userId);
23063                                 doStopUidLocked(uidRec.uid, uidRec);
23064                             }
23065                         }
23066                     }
23067                 }
23068             } finally {
23069                 if (mLocalPowerManager != null) {
23070                     mLocalPowerManager.finishUidChanges();
23071                 }
23072                 Binder.restoreCallingIdentity(callingId);
23073             }
23074         }
23075     }
23076
23077     final void idleUids() {
23078         synchronized (this) {
23079             final int N = mActiveUids.size();
23080             if (N <= 0) {
23081                 return;
23082             }
23083             final long nowElapsed = SystemClock.elapsedRealtime();
23084             final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME;
23085             long nextTime = 0;
23086             if (mLocalPowerManager != null) {
23087                 mLocalPowerManager.startUidChanges();
23088             }
23089             for (int i=N-1; i>=0; i--) {
23090                 final UidRecord uidRec = mActiveUids.valueAt(i);
23091                 final long bgTime = uidRec.lastBackgroundTime;
23092                 if (bgTime > 0 && !uidRec.idle) {
23093                     if (bgTime <= maxBgTime) {
23094                         EventLogTags.writeAmUidIdle(uidRec.uid);
23095                         uidRec.idle = true;
23096                         uidRec.setIdle = true;
23097                         doStopUidLocked(uidRec.uid, uidRec);
23098                     } else {
23099                         if (nextTime == 0 || nextTime > bgTime) {
23100                             nextTime = bgTime;
23101                         }
23102                     }
23103                 }
23104             }
23105             if (mLocalPowerManager != null) {
23106                 mLocalPowerManager.finishUidChanges();
23107             }
23108             if (nextTime > 0) {
23109                 mHandler.removeMessages(IDLE_UIDS_MSG);
23110                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
23111                         nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed);
23112             }
23113         }
23114     }
23115
23116     /**
23117      * Checks if any uid is coming from background to foreground or vice versa and if so, increments
23118      * the {@link UidRecord#curProcStateSeq} corresponding to that uid using global seq counter
23119      * {@link #mProcStateSeqCounter} and notifies the app if it needs to block.
23120      */
23121     @VisibleForTesting
23122     @GuardedBy("this")
23123     void incrementProcStateSeqAndNotifyAppsLocked() {
23124         if (mWaitForNetworkTimeoutMs <= 0) {
23125             return;
23126         }
23127         // Used for identifying which uids need to block for network.
23128         ArrayList<Integer> blockingUids = null;
23129         for (int i = mActiveUids.size() - 1; i >= 0; --i) {
23130             final UidRecord uidRec = mActiveUids.valueAt(i);
23131             // If the network is not restricted for uid, then nothing to do here.
23132             if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
23133                 continue;
23134             }
23135             if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
23136                 continue;
23137             }
23138             // If process state is not changed, then there's nothing to do.
23139             if (uidRec.setProcState == uidRec.curProcState) {
23140                 continue;
23141             }
23142             final int blockState = getBlockStateForUid(uidRec);
23143             // No need to inform the app when the blockState is NETWORK_STATE_NO_CHANGE as
23144             // there's nothing the app needs to do in this scenario.
23145             if (blockState == NETWORK_STATE_NO_CHANGE) {
23146                 continue;
23147             }
23148             synchronized (uidRec.networkStateLock) {
23149                 uidRec.curProcStateSeq = ++mProcStateSeqCounter;
23150                 if (blockState == NETWORK_STATE_BLOCK) {
23151                     if (blockingUids == null) {
23152                         blockingUids = new ArrayList<>();
23153                     }
23154                     blockingUids.add(uidRec.uid);
23155                 } else {
23156                     if (DEBUG_NETWORK) {
23157                         Slog.d(TAG_NETWORK, "uid going to background, notifying all blocking"
23158                                 + " threads for uid: " + uidRec);
23159                     }
23160                     if (uidRec.waitingForNetwork) {
23161                         uidRec.networkStateLock.notifyAll();
23162                     }
23163                 }
23164             }
23165         }
23166
23167         // There are no uids that need to block, so nothing more to do.
23168         if (blockingUids == null) {
23169             return;
23170         }
23171
23172         for (int i = mLruProcesses.size() - 1; i >= 0; --i) {
23173             final ProcessRecord app = mLruProcesses.get(i);
23174             if (!blockingUids.contains(app.uid)) {
23175                 continue;
23176             }
23177             if (!app.killedByAm && app.thread != null) {
23178                 final UidRecord uidRec = mActiveUids.get(app.uid);
23179                 try {
23180                     if (DEBUG_NETWORK) {
23181                         Slog.d(TAG_NETWORK, "Informing app thread that it needs to block: "
23182                                 + uidRec);
23183                     }
23184                     app.thread.setNetworkBlockSeq(uidRec.curProcStateSeq);
23185                 } catch (RemoteException ignored) {
23186                 }
23187             }
23188         }
23189     }
23190
23191     /**
23192      * Checks if the uid is coming from background to foreground or vice versa and returns
23193      * appropriate block state based on this.
23194      *
23195      * @return blockState based on whether the uid is coming from background to foreground or
23196      *         vice versa. If bg->fg or fg->bg, then {@link #NETWORK_STATE_BLOCK} or
23197      *         {@link #NETWORK_STATE_UNBLOCK} respectively, otherwise
23198      *         {@link #NETWORK_STATE_NO_CHANGE}.
23199      */
23200     @VisibleForTesting
23201     int getBlockStateForUid(UidRecord uidRec) {
23202         // Denotes whether uid's process state is currently allowed network access.
23203         final boolean isAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.curProcState)
23204                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.curProcState);
23205         // Denotes whether uid's process state was previously allowed network access.
23206         final boolean wasAllowed = isProcStateAllowedWhileIdleOrPowerSaveMode(uidRec.setProcState)
23207                 || isProcStateAllowedWhileOnRestrictBackground(uidRec.setProcState);
23208
23209         // When the uid is coming to foreground, AMS should inform the app thread that it should
23210         // block for the network rules to get updated before launching an activity.
23211         if (!wasAllowed && isAllowed) {
23212             return NETWORK_STATE_BLOCK;
23213         }
23214         // When the uid is going to background, AMS should inform the app thread that if an
23215         // activity launch is blocked for the network rules to get updated, it should be unblocked.
23216         if (wasAllowed && !isAllowed) {
23217             return NETWORK_STATE_UNBLOCK;
23218         }
23219         return NETWORK_STATE_NO_CHANGE;
23220     }
23221
23222     final void runInBackgroundDisabled(int uid) {
23223         synchronized (this) {
23224             UidRecord uidRec = mActiveUids.get(uid);
23225             if (uidRec != null) {
23226                 // This uid is actually running...  should it be considered background now?
23227                 if (uidRec.idle) {
23228                     doStopUidLocked(uidRec.uid, uidRec);
23229                 }
23230             } else {
23231                 // This uid isn't actually running...  still send a report about it being "stopped".
23232                 doStopUidLocked(uid, null);
23233             }
23234         }
23235     }
23236
23237     final void doStopUidLocked(int uid, final UidRecord uidRec) {
23238         mServices.stopInBackgroundLocked(uid);
23239         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
23240     }
23241
23242     /**
23243      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23244      */
23245     void tempWhitelistForPendingIntentLocked(int callerPid, int callerUid, int targetUid,
23246             long duration, String tag) {
23247         if (DEBUG_WHITELISTS) {
23248             Slog.d(TAG, "tempWhitelistForPendingIntentLocked(" + callerPid + ", " + callerUid + ", "
23249                     + targetUid + ", " + duration + ")");
23250         }
23251
23252         synchronized (mPidsSelfLocked) {
23253             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
23254             if (pr == null) {
23255                 Slog.w(TAG, "tempWhitelistForPendingIntentLocked() no ProcessRecord for pid "
23256                         + callerPid);
23257                 return;
23258             }
23259             if (!pr.whitelistManager) {
23260                 if (checkPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST, callerPid, callerUid)
23261                         != PackageManager.PERMISSION_GRANTED) {
23262                     if (DEBUG_WHITELISTS) {
23263                         Slog.d(TAG, "tempWhitelistForPendingIntentLocked() for target " + targetUid
23264                                 + ": pid " + callerPid + " is not allowed");
23265                     }
23266                     return;
23267                 }
23268             }
23269         }
23270
23271         tempWhitelistUidLocked(targetUid, duration, tag);
23272     }
23273
23274     /**
23275      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
23276      */
23277     void tempWhitelistUidLocked(int targetUid, long duration, String tag) {
23278         mPendingTempWhitelist.put(targetUid, new PendingTempWhitelist(targetUid, duration, tag));
23279         setUidTempWhitelistStateLocked(targetUid, true);
23280         mUiHandler.obtainMessage(PUSH_TEMP_WHITELIST_UI_MSG).sendToTarget();
23281     }
23282
23283     void pushTempWhitelist() {
23284         final int N;
23285         final PendingTempWhitelist[] list;
23286
23287         // First copy out the pending changes...  we need to leave them in the map for now,
23288         // in case someone needs to check what is coming up while we don't have the lock held.
23289         synchronized(this) {
23290             N = mPendingTempWhitelist.size();
23291             list = new PendingTempWhitelist[N];
23292             for (int i = 0; i < N; i++) {
23293                 list[i] = mPendingTempWhitelist.valueAt(i);
23294             }
23295         }
23296
23297         // Now safely dispatch changes to device idle controller.
23298         for (int i = 0; i < N; i++) {
23299             PendingTempWhitelist ptw = list[i];
23300             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(ptw.targetUid,
23301                     ptw.duration, true, ptw.tag);
23302         }
23303
23304         // And now we can safely remove them from the map.
23305         synchronized(this) {
23306             for (int i = 0; i < N; i++) {
23307                 PendingTempWhitelist ptw = list[i];
23308                 int index = mPendingTempWhitelist.indexOfKey(ptw.targetUid);
23309                 if (index >= 0 && mPendingTempWhitelist.valueAt(index) == ptw) {
23310                     mPendingTempWhitelist.removeAt(index);
23311                 }
23312             }
23313         }
23314     }
23315
23316     final void setAppIdTempWhitelistStateLocked(int appId, boolean onWhitelist) {
23317         boolean changed = false;
23318         for (int i=mActiveUids.size()-1; i>=0; i--) {
23319             final UidRecord uidRec = mActiveUids.valueAt(i);
23320             if (UserHandle.getAppId(uidRec.uid) == appId && uidRec.curWhitelist != onWhitelist) {
23321                 uidRec.curWhitelist = onWhitelist;
23322                 changed = true;
23323             }
23324         }
23325         if (changed) {
23326             updateOomAdjLocked();
23327         }
23328     }
23329
23330     final void setUidTempWhitelistStateLocked(int uid, boolean onWhitelist) {
23331         boolean changed = false;
23332         final UidRecord uidRec = mActiveUids.get(uid);
23333         if (uidRec != null && uidRec.curWhitelist != onWhitelist) {
23334             uidRec.curWhitelist = onWhitelist;
23335             updateOomAdjLocked();
23336         }
23337     }
23338
23339     final void trimApplications() {
23340         synchronized (this) {
23341             int i;
23342
23343             // First remove any unused application processes whose package
23344             // has been removed.
23345             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
23346                 final ProcessRecord app = mRemovedProcesses.get(i);
23347                 if (app.activities.size() == 0
23348                         && app.curReceivers.isEmpty() && app.services.size() == 0) {
23349                     Slog.i(
23350                         TAG, "Exiting empty application process "
23351                         + app.toShortString() + " ("
23352                         + (app.thread != null ? app.thread.asBinder() : null)
23353                         + ")\n");
23354                     if (app.pid > 0 && app.pid != MY_PID) {
23355                         app.kill("empty", false);
23356                     } else {
23357                         try {
23358                             app.thread.scheduleExit();
23359                         } catch (Exception e) {
23360                             // Ignore exceptions.
23361                         }
23362                     }
23363                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
23364                     mRemovedProcesses.remove(i);
23365
23366                     if (app.persistent) {
23367                         addAppLocked(app.info, null, false, null /* ABI override */);
23368                     }
23369                 }
23370             }
23371
23372             // Now update the oom adj for all processes.
23373             updateOomAdjLocked();
23374         }
23375     }
23376
23377     /** This method sends the specified signal to each of the persistent apps */
23378     public void signalPersistentProcesses(int sig) throws RemoteException {
23379         if (sig != SIGNAL_USR1) {
23380             throw new SecurityException("Only SIGNAL_USR1 is allowed");
23381         }
23382
23383         synchronized (this) {
23384             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
23385                     != PackageManager.PERMISSION_GRANTED) {
23386                 throw new SecurityException("Requires permission "
23387                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
23388             }
23389
23390             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
23391                 ProcessRecord r = mLruProcesses.get(i);
23392                 if (r.thread != null && r.persistent) {
23393                     sendSignal(r.pid, sig);
23394                 }
23395             }
23396         }
23397     }
23398
23399     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
23400         if (proc == null || proc == mProfileProc) {
23401             proc = mProfileProc;
23402             profileType = mProfileType;
23403             clearProfilerLocked();
23404         }
23405         if (proc == null) {
23406             return;
23407         }
23408         try {
23409             proc.thread.profilerControl(false, null, profileType);
23410         } catch (RemoteException e) {
23411             throw new IllegalStateException("Process disappeared");
23412         }
23413     }
23414
23415     private void clearProfilerLocked() {
23416         if (mProfilerInfo !=null && mProfilerInfo.profileFd != null) {
23417             try {
23418                 mProfilerInfo.profileFd.close();
23419             } catch (IOException e) {
23420             }
23421         }
23422         mProfileApp = null;
23423         mProfileProc = null;
23424         mProfilerInfo = null;
23425     }
23426
23427     public boolean profileControl(String process, int userId, boolean start,
23428             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
23429
23430         try {
23431             synchronized (this) {
23432                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23433                 // its own permission.
23434                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23435                         != PackageManager.PERMISSION_GRANTED) {
23436                     throw new SecurityException("Requires permission "
23437                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23438                 }
23439
23440                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
23441                     throw new IllegalArgumentException("null profile info or fd");
23442                 }
23443
23444                 ProcessRecord proc = null;
23445                 if (process != null) {
23446                     proc = findProcessLocked(process, userId, "profileControl");
23447                 }
23448
23449                 if (start && (proc == null || proc.thread == null)) {
23450                     throw new IllegalArgumentException("Unknown process: " + process);
23451                 }
23452
23453                 if (start) {
23454                     stopProfilerLocked(null, 0);
23455                     setProfileApp(proc.info, proc.processName, profilerInfo);
23456                     mProfileProc = proc;
23457                     mProfileType = profileType;
23458                     ParcelFileDescriptor fd = profilerInfo.profileFd;
23459                     try {
23460                         fd = fd.dup();
23461                     } catch (IOException e) {
23462                         fd = null;
23463                     }
23464                     profilerInfo.profileFd = fd;
23465                     proc.thread.profilerControl(start, profilerInfo, profileType);
23466                     fd = null;
23467                     try {
23468                         mProfilerInfo.profileFd.close();
23469                     } catch (IOException e) {
23470                     }
23471                     mProfilerInfo.profileFd = null;
23472                 } else {
23473                     stopProfilerLocked(proc, profileType);
23474                     if (profilerInfo != null && profilerInfo.profileFd != null) {
23475                         try {
23476                             profilerInfo.profileFd.close();
23477                         } catch (IOException e) {
23478                         }
23479                     }
23480                 }
23481
23482                 return true;
23483             }
23484         } catch (RemoteException e) {
23485             throw new IllegalStateException("Process disappeared");
23486         } finally {
23487             if (profilerInfo != null && profilerInfo.profileFd != null) {
23488                 try {
23489                     profilerInfo.profileFd.close();
23490                 } catch (IOException e) {
23491                 }
23492             }
23493         }
23494     }
23495
23496     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
23497         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
23498                 userId, true, ALLOW_FULL_ONLY, callName, null);
23499         ProcessRecord proc = null;
23500         try {
23501             int pid = Integer.parseInt(process);
23502             synchronized (mPidsSelfLocked) {
23503                 proc = mPidsSelfLocked.get(pid);
23504             }
23505         } catch (NumberFormatException e) {
23506         }
23507
23508         if (proc == null) {
23509             ArrayMap<String, SparseArray<ProcessRecord>> all
23510                     = mProcessNames.getMap();
23511             SparseArray<ProcessRecord> procs = all.get(process);
23512             if (procs != null && procs.size() > 0) {
23513                 proc = procs.valueAt(0);
23514                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
23515                     for (int i=1; i<procs.size(); i++) {
23516                         ProcessRecord thisProc = procs.valueAt(i);
23517                         if (thisProc.userId == userId) {
23518                             proc = thisProc;
23519                             break;
23520                         }
23521                     }
23522                 }
23523             }
23524         }
23525
23526         return proc;
23527     }
23528
23529     public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo,
23530             boolean runGc, String path, ParcelFileDescriptor fd) throws RemoteException {
23531
23532         try {
23533             synchronized (this) {
23534                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
23535                 // its own permission (same as profileControl).
23536                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23537                         != PackageManager.PERMISSION_GRANTED) {
23538                     throw new SecurityException("Requires permission "
23539                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23540                 }
23541
23542                 if (fd == null) {
23543                     throw new IllegalArgumentException("null fd");
23544                 }
23545
23546                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
23547                 if (proc == null || proc.thread == null) {
23548                     throw new IllegalArgumentException("Unknown process: " + process);
23549                 }
23550
23551                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23552                 if (!isDebuggable) {
23553                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23554                         throw new SecurityException("Process not debuggable: " + proc);
23555                     }
23556                 }
23557
23558                 proc.thread.dumpHeap(managed, mallocInfo, runGc, path, fd);
23559                 fd = null;
23560                 return true;
23561             }
23562         } catch (RemoteException e) {
23563             throw new IllegalStateException("Process disappeared");
23564         } finally {
23565             if (fd != null) {
23566                 try {
23567                     fd.close();
23568                 } catch (IOException e) {
23569                 }
23570             }
23571         }
23572     }
23573
23574     @Override
23575     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
23576             String reportPackage) {
23577         if (processName != null) {
23578             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
23579                     "setDumpHeapDebugLimit()");
23580         } else {
23581             synchronized (mPidsSelfLocked) {
23582                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
23583                 if (proc == null) {
23584                     throw new SecurityException("No process found for calling pid "
23585                             + Binder.getCallingPid());
23586                 }
23587                 if (!Build.IS_DEBUGGABLE
23588                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23589                     throw new SecurityException("Not running a debuggable build");
23590                 }
23591                 processName = proc.processName;
23592                 uid = proc.uid;
23593                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
23594                     throw new SecurityException("Package " + reportPackage + " is not running in "
23595                             + proc);
23596                 }
23597             }
23598         }
23599         synchronized (this) {
23600             if (maxMemSize > 0) {
23601                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
23602             } else {
23603                 if (uid != 0) {
23604                     mMemWatchProcesses.remove(processName, uid);
23605                 } else {
23606                     mMemWatchProcesses.getMap().remove(processName);
23607                 }
23608             }
23609         }
23610     }
23611
23612     @Override
23613     public void dumpHeapFinished(String path) {
23614         synchronized (this) {
23615             if (Binder.getCallingPid() != mMemWatchDumpPid) {
23616                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
23617                         + " does not match last pid " + mMemWatchDumpPid);
23618                 return;
23619             }
23620             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
23621                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
23622                         + " does not match last path " + mMemWatchDumpFile);
23623                 return;
23624             }
23625             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
23626             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
23627
23628             // Forced gc to clean up the remnant hprof fd.
23629             Runtime.getRuntime().gc();
23630         }
23631     }
23632
23633     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
23634     public void monitor() {
23635         synchronized (this) { }
23636     }
23637
23638     void onCoreSettingsChange(Bundle settings) {
23639         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
23640             ProcessRecord processRecord = mLruProcesses.get(i);
23641             try {
23642                 if (processRecord.thread != null) {
23643                     processRecord.thread.setCoreSettings(settings);
23644                 }
23645             } catch (RemoteException re) {
23646                 /* ignore */
23647             }
23648         }
23649     }
23650
23651     // Multi-user methods
23652
23653     /**
23654      * Start user, if its not already running, but don't bring it to foreground.
23655      */
23656     @Override
23657     public boolean startUserInBackground(final int userId) {
23658         return mUserController.startUser(userId, /* foreground */ false);
23659     }
23660
23661     @Override
23662     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
23663         return mUserController.unlockUser(userId, token, secret, listener);
23664     }
23665
23666     @Override
23667     public boolean switchUser(final int targetUserId) {
23668         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
23669         int currentUserId;
23670         UserInfo targetUserInfo;
23671         synchronized (this) {
23672             currentUserId = mUserController.getCurrentUserIdLocked();
23673             targetUserInfo = mUserController.getUserInfo(targetUserId);
23674             if (targetUserId == currentUserId) {
23675                 Slog.i(TAG, "user #" + targetUserId + " is already the current user");
23676                 return true;
23677             }
23678             if (targetUserInfo == null) {
23679                 Slog.w(TAG, "No user info for user #" + targetUserId);
23680                 return false;
23681             }
23682             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
23683                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
23684                         + " when device is in demo mode");
23685                 return false;
23686             }
23687             if (!targetUserInfo.supportsSwitchTo()) {
23688                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
23689                 return false;
23690             }
23691             if (targetUserInfo.isManagedProfile()) {
23692                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
23693                 return false;
23694             }
23695             mUserController.setTargetUserIdLocked(targetUserId);
23696         }
23697         if (mUserController.mUserSwitchUiEnabled) {
23698             UserInfo currentUserInfo = mUserController.getUserInfo(currentUserId);
23699             Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
23700             mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
23701             mUiHandler.sendMessage(mHandler.obtainMessage(
23702                     START_USER_SWITCH_UI_MSG, userNames));
23703         } else {
23704             mHandler.removeMessages(START_USER_SWITCH_FG_MSG);
23705             mHandler.sendMessage(mHandler.obtainMessage(
23706                     START_USER_SWITCH_FG_MSG, targetUserId, 0));
23707         }
23708         return true;
23709     }
23710
23711     void scheduleStartProfilesLocked() {
23712         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
23713             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
23714                     DateUtils.SECOND_IN_MILLIS);
23715         }
23716     }
23717
23718     @Override
23719     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
23720         return mUserController.stopUser(userId, force, callback);
23721     }
23722
23723     @Override
23724     public UserInfo getCurrentUser() {
23725         return mUserController.getCurrentUser();
23726     }
23727
23728     String getStartedUserState(int userId) {
23729         synchronized (this) {
23730             final UserState userState = mUserController.getStartedUserStateLocked(userId);
23731             return UserState.stateToString(userState.state);
23732         }
23733     }
23734
23735     @Override
23736     public boolean isUserRunning(int userId, int flags) {
23737         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
23738                 && checkCallingPermission(INTERACT_ACROSS_USERS)
23739                     != PackageManager.PERMISSION_GRANTED) {
23740             String msg = "Permission Denial: isUserRunning() from pid="
23741                     + Binder.getCallingPid()
23742                     + ", uid=" + Binder.getCallingUid()
23743                     + " requires " + INTERACT_ACROSS_USERS;
23744             Slog.w(TAG, msg);
23745             throw new SecurityException(msg);
23746         }
23747         synchronized (this) {
23748             return mUserController.isUserRunningLocked(userId, flags);
23749         }
23750     }
23751
23752     @Override
23753     public int[] getRunningUserIds() {
23754         if (checkCallingPermission(INTERACT_ACROSS_USERS)
23755                 != PackageManager.PERMISSION_GRANTED) {
23756             String msg = "Permission Denial: isUserRunning() from pid="
23757                     + Binder.getCallingPid()
23758                     + ", uid=" + Binder.getCallingUid()
23759                     + " requires " + INTERACT_ACROSS_USERS;
23760             Slog.w(TAG, msg);
23761             throw new SecurityException(msg);
23762         }
23763         synchronized (this) {
23764             return mUserController.getStartedUserArrayLocked();
23765         }
23766     }
23767
23768     @Override
23769     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
23770         mUserController.registerUserSwitchObserver(observer, name);
23771     }
23772
23773     @Override
23774     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
23775         mUserController.unregisterUserSwitchObserver(observer);
23776     }
23777
23778     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
23779         if (info == null) return null;
23780         ApplicationInfo newInfo = new ApplicationInfo(info);
23781         newInfo.initForUser(userId);
23782         return newInfo;
23783     }
23784
23785     public boolean isUserStopped(int userId) {
23786         synchronized (this) {
23787             return mUserController.getStartedUserStateLocked(userId) == null;
23788         }
23789     }
23790
23791     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
23792         if (aInfo == null
23793                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
23794             return aInfo;
23795         }
23796
23797         ActivityInfo info = new ActivityInfo(aInfo);
23798         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
23799         return info;
23800     }
23801
23802     private boolean processSanityChecksLocked(ProcessRecord process) {
23803         if (process == null || process.thread == null) {
23804             return false;
23805         }
23806
23807         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
23808         if (!isDebuggable) {
23809             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
23810                 return false;
23811             }
23812         }
23813
23814         return true;
23815     }
23816
23817     public boolean startBinderTracking() throws RemoteException {
23818         synchronized (this) {
23819             mBinderTransactionTrackingEnabled = true;
23820             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23821             // permission (same as profileControl).
23822             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23823                     != PackageManager.PERMISSION_GRANTED) {
23824                 throw new SecurityException("Requires permission "
23825                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23826             }
23827
23828             for (int i = 0; i < mLruProcesses.size(); i++) {
23829                 ProcessRecord process = mLruProcesses.get(i);
23830                 if (!processSanityChecksLocked(process)) {
23831                     continue;
23832                 }
23833                 try {
23834                     process.thread.startBinderTracking();
23835                 } catch (RemoteException e) {
23836                     Log.v(TAG, "Process disappared");
23837                 }
23838             }
23839             return true;
23840         }
23841     }
23842
23843     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
23844         try {
23845             synchronized (this) {
23846                 mBinderTransactionTrackingEnabled = false;
23847                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
23848                 // permission (same as profileControl).
23849                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
23850                         != PackageManager.PERMISSION_GRANTED) {
23851                     throw new SecurityException("Requires permission "
23852                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
23853                 }
23854
23855                 if (fd == null) {
23856                     throw new IllegalArgumentException("null fd");
23857                 }
23858
23859                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
23860                 pw.println("Binder transaction traces for all processes.\n");
23861                 for (ProcessRecord process : mLruProcesses) {
23862                     if (!processSanityChecksLocked(process)) {
23863                         continue;
23864                     }
23865
23866                     pw.println("Traces for process: " + process.processName);
23867                     pw.flush();
23868                     try {
23869                         TransferPipe tp = new TransferPipe();
23870                         try {
23871                             process.thread.stopBinderTrackingAndDump(tp.getWriteFd());
23872                             tp.go(fd.getFileDescriptor());
23873                         } finally {
23874                             tp.kill();
23875                         }
23876                     } catch (IOException e) {
23877                         pw.println("Failure while dumping IPC traces from " + process +
23878                                 ".  Exception: " + e);
23879                         pw.flush();
23880                     } catch (RemoteException e) {
23881                         pw.println("Got a RemoteException while dumping IPC traces from " +
23882                                 process + ".  Exception: " + e);
23883                         pw.flush();
23884                     }
23885                 }
23886                 fd = null;
23887                 return true;
23888             }
23889         } finally {
23890             if (fd != null) {
23891                 try {
23892                     fd.close();
23893                 } catch (IOException e) {
23894                 }
23895             }
23896         }
23897     }
23898
23899     @VisibleForTesting
23900     final class LocalService extends ActivityManagerInternal {
23901         @Override
23902         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
23903                 int targetUserId) {
23904             synchronized (ActivityManagerService.this) {
23905                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
23906                         targetPkg, intent, null, targetUserId);
23907             }
23908         }
23909
23910         @Override
23911         public String checkContentProviderAccess(String authority, int userId) {
23912             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
23913         }
23914
23915         @Override
23916         public void onWakefulnessChanged(int wakefulness) {
23917             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
23918         }
23919
23920         @Override
23921         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
23922                 String processName, String abiOverride, int uid, Runnable crashHandler) {
23923             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
23924                     processName, abiOverride, uid, crashHandler);
23925         }
23926
23927         @Override
23928         public SleepToken acquireSleepToken(String tag, int displayId) {
23929             Preconditions.checkNotNull(tag);
23930             return ActivityManagerService.this.acquireSleepToken(tag, displayId);
23931         }
23932
23933         @Override
23934         public ComponentName getHomeActivityForUser(int userId) {
23935             synchronized (ActivityManagerService.this) {
23936                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
23937                 return homeActivity == null ? null : homeActivity.realActivity;
23938             }
23939         }
23940
23941         @Override
23942         public void onUserRemoved(int userId) {
23943             synchronized (ActivityManagerService.this) {
23944                 ActivityManagerService.this.onUserStoppedLocked(userId);
23945             }
23946             mBatteryStatsService.onUserRemoved(userId);
23947         }
23948
23949         @Override
23950         public void onLocalVoiceInteractionStarted(IBinder activity,
23951                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
23952             synchronized (ActivityManagerService.this) {
23953                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
23954                         voiceSession, voiceInteractor);
23955             }
23956         }
23957
23958         @Override
23959         public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
23960             synchronized (ActivityManagerService.this) {
23961                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(
23962                         reasons, timestamp);
23963             }
23964         }
23965
23966         @Override
23967         public void notifyAppTransitionFinished() {
23968             synchronized (ActivityManagerService.this) {
23969                 mStackSupervisor.notifyAppTransitionDone();
23970             }
23971         }
23972
23973         @Override
23974         public void notifyAppTransitionCancelled() {
23975             synchronized (ActivityManagerService.this) {
23976                 mStackSupervisor.notifyAppTransitionDone();
23977             }
23978         }
23979
23980         @Override
23981         public List<IBinder> getTopVisibleActivities() {
23982             synchronized (ActivityManagerService.this) {
23983                 return mStackSupervisor.getTopVisibleActivities();
23984             }
23985         }
23986
23987         @Override
23988         public void notifyDockedStackMinimizedChanged(boolean minimized) {
23989             synchronized (ActivityManagerService.this) {
23990                 mStackSupervisor.setDockedStackMinimized(minimized);
23991             }
23992         }
23993
23994         @Override
23995         public void killForegroundAppsForUser(int userHandle) {
23996             synchronized (ActivityManagerService.this) {
23997                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
23998                 final int NP = mProcessNames.getMap().size();
23999                 for (int ip = 0; ip < NP; ip++) {
24000                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
24001                     final int NA = apps.size();
24002                     for (int ia = 0; ia < NA; ia++) {
24003                         final ProcessRecord app = apps.valueAt(ia);
24004                         if (app.persistent) {
24005                             // We don't kill persistent processes.
24006                             continue;
24007                         }
24008                         if (app.removed) {
24009                             procs.add(app);
24010                         } else if (app.userId == userHandle && app.foregroundActivities) {
24011                             app.removed = true;
24012                             procs.add(app);
24013                         }
24014                     }
24015                 }
24016
24017                 final int N = procs.size();
24018                 for (int i = 0; i < N; i++) {
24019                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
24020                 }
24021             }
24022         }
24023
24024         @Override
24025         public void setPendingIntentWhitelistDuration(IIntentSender target, IBinder whitelistToken,
24026                 long duration) {
24027             if (!(target instanceof PendingIntentRecord)) {
24028                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
24029                 return;
24030             }
24031             synchronized (ActivityManagerService.this) {
24032                 ((PendingIntentRecord) target).setWhitelistDurationLocked(whitelistToken, duration);
24033             }
24034         }
24035
24036         @Override
24037         public void setDeviceIdleWhitelist(int[] appids) {
24038             synchronized (ActivityManagerService.this) {
24039                 mDeviceIdleWhitelist = appids;
24040             }
24041         }
24042
24043         @Override
24044         public void updateDeviceIdleTempWhitelist(int[] appids, int changingAppId, boolean adding) {
24045             synchronized (ActivityManagerService.this) {
24046                 mDeviceIdleTempWhitelist = appids;
24047                 setAppIdTempWhitelistStateLocked(changingAppId, adding);
24048             }
24049         }
24050
24051         @Override
24052         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
24053                 int userId) {
24054             Preconditions.checkNotNull(values, "Configuration must not be null");
24055             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
24056             synchronized (ActivityManagerService.this) {
24057                 updateConfigurationLocked(values, null, false, true, userId,
24058                         false /* deferResume */);
24059             }
24060         }
24061
24062         @Override
24063         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
24064                 Bundle bOptions) {
24065             Preconditions.checkNotNull(intents, "intents");
24066             final String[] resolvedTypes = new String[intents.length];
24067             for (int i = 0; i < intents.length; i++) {
24068                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
24069             }
24070
24071             // UID of the package on user userId.
24072             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
24073             // packageUid may not be initialized.
24074             int packageUid = 0;
24075             try {
24076                 packageUid = AppGlobals.getPackageManager().getPackageUid(
24077                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
24078             } catch (RemoteException e) {
24079                 // Shouldn't happen.
24080             }
24081
24082             synchronized (ActivityManagerService.this) {
24083                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
24084                         /*resultTo*/ null, bOptions, userId);
24085             }
24086         }
24087
24088         @Override
24089         public int getUidProcessState(int uid) {
24090             return getUidState(uid);
24091         }
24092
24093         @Override
24094         public void notifyKeyguardFlagsChanged(@Nullable Runnable callback) {
24095             synchronized (ActivityManagerService.this) {
24096
24097                 // We might change the visibilities here, so prepare an empty app transition which
24098                 // might be overridden later if we actually change visibilities.
24099                 final boolean wasTransitionSet =
24100                         mWindowManager.getPendingAppTransition() != TRANSIT_NONE;
24101                 if (!wasTransitionSet) {
24102                     mWindowManager.prepareAppTransition(TRANSIT_NONE,
24103                             false /* alwaysKeepCurrent */);
24104                 }
24105                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24106
24107                 // If there was a transition set already we don't want to interfere with it as we
24108                 // might be starting it too early.
24109                 if (!wasTransitionSet) {
24110                     mWindowManager.executeAppTransition();
24111                 }
24112             }
24113             if (callback != null) {
24114                 callback.run();
24115             }
24116         }
24117
24118         @Override
24119         public boolean isSystemReady() {
24120             // no need to synchronize(this) just to read & return the value
24121             return mSystemReady;
24122         }
24123
24124         @Override
24125         public void notifyKeyguardTrustedChanged() {
24126             synchronized (ActivityManagerService.this) {
24127                 if (mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)) {
24128                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
24129                 }
24130             }
24131         }
24132
24133         /**
24134          * Sets if the given pid has an overlay UI or not.
24135          *
24136          * @param pid The pid we are setting overlay UI for.
24137          * @param hasOverlayUi True if the process has overlay UI.
24138          * @see android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY
24139          */
24140         @Override
24141         public void setHasOverlayUi(int pid, boolean hasOverlayUi) {
24142             synchronized (ActivityManagerService.this) {
24143                 final ProcessRecord pr;
24144                 synchronized (mPidsSelfLocked) {
24145                     pr = mPidsSelfLocked.get(pid);
24146                     if (pr == null) {
24147                         Slog.w(TAG, "setHasOverlayUi called on unknown pid: " + pid);
24148                         return;
24149                     }
24150                 }
24151                 if (pr.hasOverlayUi == hasOverlayUi) {
24152                     return;
24153                 }
24154                 pr.hasOverlayUi = hasOverlayUi;
24155                 //Slog.i(TAG, "Setting hasOverlayUi=" + pr.hasOverlayUi + " for pid=" + pid);
24156                 updateOomAdjLocked(pr, true);
24157             }
24158         }
24159
24160         /**
24161          * Called after the network policy rules are updated by
24162          * {@link com.android.server.net.NetworkPolicyManagerService} for a specific {@param uid}
24163          * and {@param procStateSeq}.
24164          */
24165         @Override
24166         public void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq) {
24167             if (DEBUG_NETWORK) {
24168                 Slog.d(TAG_NETWORK, "Got update from NPMS for uid: "
24169                         + uid + " seq: " + procStateSeq);
24170             }
24171             UidRecord record;
24172             synchronized (ActivityManagerService.this) {
24173                 record = mActiveUids.get(uid);
24174                 if (record == null) {
24175                     if (DEBUG_NETWORK) {
24176                         Slog.d(TAG_NETWORK, "No active uidRecord for uid: " + uid
24177                                 + " procStateSeq: " + procStateSeq);
24178                     }
24179                     return;
24180                 }
24181             }
24182             synchronized (record.networkStateLock) {
24183                 if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24184                     if (DEBUG_NETWORK) {
24185                         Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
24186                                 + " been handled for uid: " + uid);
24187                     }
24188                     return;
24189                 }
24190                 record.lastNetworkUpdatedProcStateSeq = procStateSeq;
24191                 if (record.curProcStateSeq > procStateSeq) {
24192                     if (DEBUG_NETWORK) {
24193                         Slog.d(TAG_NETWORK, "No need to handle older seq no., Uid: " + uid
24194                                 + ", curProcstateSeq: " + record.curProcStateSeq
24195                                 + ", procStateSeq: " + procStateSeq);
24196                     }
24197                     return;
24198                 }
24199                 if (record.waitingForNetwork) {
24200                     if (DEBUG_NETWORK) {
24201                         Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
24202                                 + ", procStateSeq: " + procStateSeq);
24203                     }
24204                     record.networkStateLock.notifyAll();
24205                 }
24206             }
24207         }
24208
24209         /**
24210          * Called after virtual display Id is updated by
24211          * {@link com.android.server.vr.Vr2dDisplay} with a specific
24212          * {@param vrVr2dDisplayId}.
24213          */
24214         @Override
24215         public void setVr2dDisplayId(int vr2dDisplayId) {
24216             if (DEBUG_STACK) {
24217                 Slog.d(TAG, "setVr2dDisplayId called for: " +
24218                         vr2dDisplayId);
24219             }
24220             synchronized (ActivityManagerService.this) {
24221                 mVr2dDisplayId = vr2dDisplayId;
24222             }
24223         }
24224
24225         @Override
24226         public void saveANRState(String reason) {
24227             synchronized (ActivityManagerService.this) {
24228                 final StringWriter sw = new StringWriter();
24229                 final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
24230                 pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
24231                 if (reason != null) {
24232                     pw.println("  Reason: " + reason);
24233                 }
24234                 pw.println();
24235                 mActivityStarter.dump(pw, "  ", null);
24236                 pw.println();
24237                 pw.println("-------------------------------------------------------------------------------");
24238                 dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
24239                         true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
24240                         "" /* header */);
24241                 pw.println();
24242                 pw.close();
24243
24244                 mLastANRState = sw.toString();
24245             }
24246         }
24247
24248         @Override
24249         public void clearSavedANRState() {
24250             synchronized (ActivityManagerService.this) {
24251                 mLastANRState = null;
24252             }
24253         }
24254
24255         @Override
24256         public void setFocusedActivity(IBinder token) {
24257             synchronized (ActivityManagerService.this) {
24258                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
24259                 if (r == null) {
24260                     throw new IllegalArgumentException(
24261                             "setFocusedActivity: No activity record matching token=" + token);
24262                 }
24263                 if (mStackSupervisor.moveFocusableActivityStackToFrontLocked(
24264                         r, "setFocusedActivity")) {
24265                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
24266                 }
24267             }
24268         }
24269
24270         @Override
24271         public boolean hasRunningActivity(int uid, @Nullable String packageName) {
24272             if (packageName == null) return false;
24273
24274             synchronized (ActivityManagerService.this) {
24275                 for (int i = 0; i < mLruProcesses.size(); i++) {
24276                     final ProcessRecord processRecord = mLruProcesses.get(i);
24277                     if (processRecord.uid == uid) {
24278                         for (int j = 0; j < processRecord.activities.size(); j++) {
24279                             final ActivityRecord activityRecord = processRecord.activities.get(j);
24280                             if (packageName.equals(activityRecord.packageName)) {
24281                                 return true;
24282                             }
24283                         }
24284                     }
24285                 }
24286             }
24287             return false;
24288         }
24289     }
24290
24291     /**
24292      * Called by app main thread to wait for the network policy rules to get updated.
24293      *
24294      * @param procStateSeq The sequence number indicating the process state change that the main
24295      *                     thread is interested in.
24296      */
24297     @Override
24298     public void waitForNetworkStateUpdate(long procStateSeq) {
24299         final int callingUid = Binder.getCallingUid();
24300         if (DEBUG_NETWORK) {
24301             Slog.d(TAG_NETWORK, "Called from " + callingUid + " to wait for seq: " + procStateSeq);
24302         }
24303         UidRecord record;
24304         synchronized (this) {
24305             record = mActiveUids.get(callingUid);
24306             if (record == null) {
24307                 return;
24308             }
24309         }
24310         synchronized (record.networkStateLock) {
24311             if (record.lastDispatchedProcStateSeq < procStateSeq) {
24312                 if (DEBUG_NETWORK) {
24313                     Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
24314                             + "dispatched to NPMS yet, so don't wait. Uid: " + callingUid
24315                             + " lastProcStateSeqDispatchedToObservers: "
24316                             + record.lastDispatchedProcStateSeq);
24317                 }
24318                 return;
24319             }
24320             if (record.curProcStateSeq > procStateSeq) {
24321                 if (DEBUG_NETWORK) {
24322                     Slog.d(TAG_NETWORK, "Ignore the wait requests for older seq numbers. Uid: "
24323                             + callingUid + ", curProcStateSeq: " + record.curProcStateSeq
24324                             + ", procStateSeq: " + procStateSeq);
24325                 }
24326                 return;
24327             }
24328             if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
24329                 if (DEBUG_NETWORK) {
24330                     Slog.d(TAG_NETWORK, "Network rules have been already updated for seq no. "
24331                             + procStateSeq + ", so no need to wait. Uid: "
24332                             + callingUid + ", lastProcStateSeqWithUpdatedNetworkState: "
24333                             + record.lastNetworkUpdatedProcStateSeq);
24334                 }
24335                 return;
24336             }
24337             try {
24338                 if (DEBUG_NETWORK) {
24339                     Slog.d(TAG_NETWORK, "Starting to wait for the network rules update."
24340                         + " Uid: " + callingUid + " procStateSeq: " + procStateSeq);
24341                 }
24342                 final long startTime = SystemClock.uptimeMillis();
24343                 record.waitingForNetwork = true;
24344                 record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
24345                 record.waitingForNetwork = false;
24346                 final long totalTime = SystemClock.uptimeMillis() - startTime;
24347                 if (totalTime >= mWaitForNetworkTimeoutMs || DEBUG_NETWORK) {
24348                     Slog.wtf(TAG_NETWORK, "Total time waited for network rules to get updated: "
24349                             + totalTime + ". Uid: " + callingUid + " procStateSeq: "
24350                             + procStateSeq + " UidRec: " + record
24351                             + " validateUidRec: " + mValidateUids.get(callingUid));
24352                 }
24353             } catch (InterruptedException e) {
24354                 Thread.currentThread().interrupt();
24355             }
24356         }
24357     }
24358
24359     public void waitForBroadcastIdle(PrintWriter pw) {
24360         enforceCallingPermission(permission.DUMP, "waitForBroadcastIdle()");
24361         while (true) {
24362             boolean idle = true;
24363             synchronized (this) {
24364                 for (BroadcastQueue queue : mBroadcastQueues) {
24365                     if (!queue.isIdle()) {
24366                         final String msg = "Waiting for queue " + queue + " to become idle...";
24367                         pw.println(msg);
24368                         pw.flush();
24369                         Slog.v(TAG, msg);
24370                         idle = false;
24371                     }
24372                 }
24373             }
24374
24375             if (idle) {
24376                 final String msg = "All broadcast queues are idle!";
24377                 pw.println(msg);
24378                 pw.flush();
24379                 Slog.v(TAG, msg);
24380                 return;
24381             } else {
24382                 SystemClock.sleep(1000);
24383             }
24384         }
24385     }
24386
24387     /**
24388      * Return the user id of the last resumed activity.
24389      */
24390     @Override
24391     public @UserIdInt int getLastResumedActivityUserId() {
24392         enforceCallingPermission(
24393                 permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
24394         synchronized (this) {
24395             if (mLastResumedActivity == null) {
24396                 return mUserController.getCurrentUserIdLocked();
24397             }
24398             return mLastResumedActivity.userId;
24399         }
24400     }
24401
24402     /**
24403      * An implementation of IAppTask, that allows an app to manage its own tasks via
24404      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
24405      * only the process that calls getAppTasks() can call the AppTask methods.
24406      */
24407     class AppTaskImpl extends IAppTask.Stub {
24408         private int mTaskId;
24409         private int mCallingUid;
24410
24411         public AppTaskImpl(int taskId, int callingUid) {
24412             mTaskId = taskId;
24413             mCallingUid = callingUid;
24414         }
24415
24416         private void checkCaller() {
24417             if (mCallingUid != Binder.getCallingUid()) {
24418                 throw new SecurityException("Caller " + mCallingUid
24419                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
24420             }
24421         }
24422
24423         @Override
24424         public void finishAndRemoveTask() {
24425             checkCaller();
24426
24427             synchronized (ActivityManagerService.this) {
24428                 long origId = Binder.clearCallingIdentity();
24429                 try {
24430                     // We remove the task from recents to preserve backwards
24431                     if (!mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
24432                             REMOVE_FROM_RECENTS)) {
24433                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24434                     }
24435                 } finally {
24436                     Binder.restoreCallingIdentity(origId);
24437                 }
24438             }
24439         }
24440
24441         @Override
24442         public ActivityManager.RecentTaskInfo getTaskInfo() {
24443             checkCaller();
24444
24445             synchronized (ActivityManagerService.this) {
24446                 long origId = Binder.clearCallingIdentity();
24447                 try {
24448                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24449                     if (tr == null) {
24450                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24451                     }
24452                     return createRecentTaskInfoFromTaskRecord(tr);
24453                 } finally {
24454                     Binder.restoreCallingIdentity(origId);
24455                 }
24456             }
24457         }
24458
24459         @Override
24460         public void moveToFront() {
24461             checkCaller();
24462             // Will bring task to front if it already has a root activity.
24463             final long origId = Binder.clearCallingIdentity();
24464             try {
24465                 synchronized (this) {
24466                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
24467                 }
24468             } finally {
24469                 Binder.restoreCallingIdentity(origId);
24470             }
24471         }
24472
24473         @Override
24474         public int startActivity(IBinder whoThread, String callingPackage,
24475                 Intent intent, String resolvedType, Bundle bOptions) {
24476             checkCaller();
24477
24478             int callingUser = UserHandle.getCallingUserId();
24479             TaskRecord tr;
24480             IApplicationThread appThread;
24481             synchronized (ActivityManagerService.this) {
24482                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24483                 if (tr == null) {
24484                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24485                 }
24486                 appThread = IApplicationThread.Stub.asInterface(whoThread);
24487                 if (appThread == null) {
24488                     throw new IllegalArgumentException("Bad app thread " + appThread);
24489                 }
24490             }
24491             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
24492                     resolvedType, null, null, null, null, 0, 0, null, null,
24493                     null, bOptions, false, callingUser, tr, "AppTaskImpl");
24494         }
24495
24496         @Override
24497         public void setExcludeFromRecents(boolean exclude) {
24498             checkCaller();
24499
24500             synchronized (ActivityManagerService.this) {
24501                 long origId = Binder.clearCallingIdentity();
24502                 try {
24503                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
24504                     if (tr == null) {
24505                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
24506                     }
24507                     Intent intent = tr.getBaseIntent();
24508                     if (exclude) {
24509                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24510                     } else {
24511                         intent.setFlags(intent.getFlags()
24512                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
24513                     }
24514                 } finally {
24515                     Binder.restoreCallingIdentity(origId);
24516                 }
24517             }
24518         }
24519     }
24520
24521     /**
24522      * Kill processes for the user with id userId and that depend on the package named packageName
24523      */
24524     @Override
24525     public void killPackageDependents(String packageName, int userId) {
24526         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
24527         if (packageName == null) {
24528             throw new NullPointerException(
24529                     "Cannot kill the dependents of a package without its name.");
24530         }
24531
24532         long callingId = Binder.clearCallingIdentity();
24533         IPackageManager pm = AppGlobals.getPackageManager();
24534         int pkgUid = -1;
24535         try {
24536             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
24537         } catch (RemoteException e) {
24538         }
24539         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
24540             throw new IllegalArgumentException(
24541                     "Cannot kill dependents of non-existing package " + packageName);
24542         }
24543         try {
24544             synchronized(this) {
24545                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
24546                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
24547                         "dep: " + packageName);
24548             }
24549         } finally {
24550             Binder.restoreCallingIdentity(callingId);
24551         }
24552     }
24553
24554     @Override
24555     public void dismissKeyguard(IBinder token, IKeyguardDismissCallback callback)
24556             throws RemoteException {
24557         final long callingId = Binder.clearCallingIdentity();
24558         try {
24559             mKeyguardController.dismissKeyguard(token, callback);
24560         } finally {
24561             Binder.restoreCallingIdentity(callingId);
24562         }
24563     }
24564
24565     @Override
24566     public int restartUserInBackground(final int userId) {
24567         return mUserController.restartUser(userId, /* foreground */ false);
24568     }
24569
24570     @Override
24571     public void scheduleApplicationInfoChanged(List<String> packageNames, int userId) {
24572         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
24573                 "scheduleApplicationInfoChanged()");
24574
24575         synchronized (this) {
24576             final long origId = Binder.clearCallingIdentity();
24577             try {
24578                 updateApplicationInfoLocked(packageNames, userId);
24579             } finally {
24580                 Binder.restoreCallingIdentity(origId);
24581             }
24582         }
24583     }
24584
24585     void updateApplicationInfoLocked(@NonNull List<String> packagesToUpdate, int userId) {
24586         final boolean updateFrameworkRes = packagesToUpdate.contains("android");
24587         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
24588             final ProcessRecord app = mLruProcesses.get(i);
24589             if (app.thread == null) {
24590                 continue;
24591             }
24592
24593             if (userId != UserHandle.USER_ALL && app.userId != userId) {
24594                 continue;
24595             }
24596
24597             final int packageCount = app.pkgList.size();
24598             for (int j = 0; j < packageCount; j++) {
24599                 final String packageName = app.pkgList.keyAt(j);
24600                 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) {
24601                     try {
24602                         final ApplicationInfo ai = AppGlobals.getPackageManager()
24603                                 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId);
24604                         if (ai != null) {
24605                             app.thread.scheduleApplicationInfoChanged(ai);
24606                         }
24607                     } catch (RemoteException e) {
24608                         Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
24609                                     packageName, app));
24610                     }
24611                 }
24612             }
24613         }
24614     }
24615
24616     /**
24617      * Attach an agent to the specified process (proces name or PID)
24618      */
24619     public void attachAgent(String process, String path) {
24620         try {
24621             synchronized (this) {
24622                 ProcessRecord proc = findProcessLocked(process, UserHandle.USER_SYSTEM, "attachAgent");
24623                 if (proc == null || proc.thread == null) {
24624                     throw new IllegalArgumentException("Unknown process: " + process);
24625                 }
24626
24627                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
24628                 if (!isDebuggable) {
24629                     if ((proc.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
24630                         throw new SecurityException("Process not debuggable: " + proc);
24631                     }
24632                 }
24633
24634                 proc.thread.attachAgent(path);
24635             }
24636         } catch (RemoteException e) {
24637             throw new IllegalStateException("Process disappeared");
24638         }
24639     }
24640
24641     @VisibleForTesting
24642     public static class Injector {
24643         private NetworkManagementInternal mNmi;
24644
24645         public Context getContext() {
24646             return null;
24647         }
24648
24649         public AppOpsService getAppOpsService(File file, Handler handler) {
24650             return new AppOpsService(file, handler);
24651         }
24652
24653         public Handler getUiHandler(ActivityManagerService service) {
24654             return service.new UiHandler();
24655         }
24656
24657         public boolean isNetworkRestrictedForUid(int uid) {
24658             if (ensureHasNetworkManagementInternal()) {
24659                 return mNmi.isNetworkRestrictedForUid(uid);
24660             }
24661             return false;
24662         }
24663
24664         private boolean ensureHasNetworkManagementInternal() {
24665             if (mNmi == null) {
24666                 mNmi = LocalServices.getService(NetworkManagementInternal.class);
24667             }
24668             return mNmi != null;
24669         }
24670     }
24671
24672     @Override
24673     public void setShowWhenLocked(IBinder token, boolean showWhenLocked)
24674             throws RemoteException {
24675         synchronized (this) {
24676             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24677             if (r == null) {
24678                 return;
24679             }
24680             final long origId = Binder.clearCallingIdentity();
24681             try {
24682                 r.setShowWhenLocked(showWhenLocked);
24683             } finally {
24684                 Binder.restoreCallingIdentity(origId);
24685             }
24686         }
24687     }
24688
24689     @Override
24690     public void setTurnScreenOn(IBinder token, boolean turnScreenOn) throws RemoteException {
24691         synchronized (this) {
24692             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
24693             if (r == null) {
24694                 return;
24695             }
24696             final long origId = Binder.clearCallingIdentity();
24697             try {
24698                 r.setTurnScreenOn(turnScreenOn);
24699             } finally {
24700                 Binder.restoreCallingIdentity(origId);
24701             }
24702         }
24703     }
24704 }